如何模拟用 Python Flask route() 装饰的方法

Lqu*_*yvg 5 mocking flask python-unittest

我需要对 Flask 装饰的方法是否route()被调用进行单元测试。

如果可能的话,我想在修改被测原始代码的情况下执行此操作,因此模拟该方法将完美地满足我的要求。

因此,我要问这个关于如何模拟装饰请求方法的具体问题(我想强调这一点,以避免人们在不太具体的答案上浪费时间)...

示例应用jflask.py

from flask import Flask
app = Flask(__name__)
app.config.from_object(__name__)

@app.route('/hello')           # This method represents the code under test.
def hello():                   # I want to assert that this method gets
    return 'Hello, World'      # called without modifying this code.

if __name__ == "__main__":
    app.run()
Run Code Online (Sandbox Code Playgroud)

在单元测试中,我@patch()用来模拟该方法,以便我可以断言它被调用,但断言失败。即当我期望它时,不会调用模拟方法。

示例单元测试test_hello.py

import unittest
import jflask
from unittest.mock import patch

class jTest(unittest.TestCase):
    def setUp(self):
        #jflask.app.testing = True
        self.app = jflask.app.test_client()

    @patch('jflask.hello')                # mock the hello() method
    def test_hello(self, mock_method):
        rv = self.app.get('/hello')
        mock_method.assert_called()    # this assertion fails
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么 ?


背景

关于我试图测试的实际行为的一些背景信息(因为上面只是一个浓缩的测试用例,它本身可能看起来并不完全正常)。

在我进行单元测试的实际代码中,before_request()为应用程序安装了一个处理程序。这在每个请求被处理之前被 Flask 调用,并且在某些情况下,这个处理程序被设计为返回一个响应值,这会导致 Flask 请求处理停止(在这个应用程序的情况下,这个功能用于集中验证请求参数),这样通常的路由请求处理程序将(故意)不被调用。

我的单元测试需要根据情况适当地断言请求处理是停止还是继续。因此,我的测试需要模拟真正的请求处理程序并断言它是否被调用。

Dan*_*Dan 0

这有点 hacky,但你可以注入一个记录器。

@app.route(...):
def hello(logger=None):
  logger = logger or self.logger
  logger.info(...)
  return ...

def test_...(self):
  logger = MagicMock()
  self.app.get(logger)
  self.assertTrue(logger.info.called)
Run Code Online (Sandbox Code Playgroud)