title: use mock server in testing flask app using pytest
body: <p><strong>tl;dr</strong>
  I am looking for the best practice for testing a flask app which uses external APIs under its routes, and probably this is where I have to simulate the external APIs using mock servers in the testing stage.</p>
  
  <hr>
  
  <p>Ok, all I have got searching <code>pytest-mock</code> and similar packages is that I can mock a function and have the results prepared for test assertions. But unfortunately I cannot find a best-practice explanation for my situation:</p>
  
  <p>I have a flask app, under some of the routes of which I use external APIs and I want to use mock servers replacing those real external API URLs. I have come to two apparently fair solutions:</p>
  
  <p><strong>Using test URLs when testing</strong></p>
  
  <p>What I have got so far is that I can set different URLs dynamically by <code>app.config</code> so that in my <code>conftest.py</code> I can invoke using test URLs, and in reality, my app will be launched by the main URLs. Now my question here is how I can run a mock server <em>automatically</em> in the <code>pytest fixture</code> setup stage to occupy the test URLs localhost ports. I said automatically because I can naively run a manual mock app in background myself, which is silly and useless for automated testing purposes</p>
  
  <p><strong>Using a mock function instead of sending the request to the main URL</strong></p>
  
  <p>I have realized that I can setup a mocker which is a function returning my desired value, and use it alongside calling my to-be-tested app. but the point is I want to use the mock <em>inside</em> my app, not comparing the returning value with a mock generated value</p>
  
  <p>So where am I and what should I do?!</p>
  
  <p>Here is a sample:</p>
  
  <p>My flask app:</p>
  
  <pre><code>app = Flask(__name__)
  
  @app.route('/test')
  def test():
      value = request.args.get('dummy_val')
  
      # using external APIs
      # This is where I need mock server
      output = requests.get(
           'http://external.api/some/url',
           params={'val':value}
      )
      return output*2
  </code></pre>
  
  <p>my test file:</p>
  
  <pre><code>def test_can_double_value(test_client):
      result = test_client('/test', query_string={'dummy_val':'foo'})
      # test if status code == 200
      # test if string equals to something
      # blah blah blah
  </code></pre>