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

如何模拟用Python Flask route()修饰的方法,flask,mocking,python-unittest,Flask,Mocking,Python Unittest,我需要单元测试由Flaskroute()修饰的方法是否被调用 如果可能的话,我希望在不修改测试中的原始代码的情况下执行此操作,因此模拟该方法将完全符合我的要求 因此,我提出了一个关于如何模拟修饰请求方法的具体问题(我想强调这一点,以避免人们用不太具体的答案浪费时间) 示例应用程序jflask.py: from flask import Flask app = Flask(__name__) app.config.from_object(__name__) @app.route('/hello'

我需要单元测试由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()
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
在单元测试中,我使用
@patch()
模拟该方法,以便断言调用了它,但断言失败。也就是说,当我期望mock方法被调用时,它不会被调用

样本单元测试
测试\u hello.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()
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
我做错了什么


背景

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

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

我的单元测试需要断言请求处理已停止 或继续,视情况而定。 因此,我的测试需要模拟真实的请求处理程序并断言
它是否被调用。

这有点麻烦,但您可以插入一个记录器

@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)

想想什么时候应用模拟-您已经执行了测试代码中的定义,Flask已经注册了原始的
hello
。这似乎非常接近于测试框架而不是您的代码,而且肯定是测试实现而不是行为;不管调用了哪种特定的方法,都可以测试您是否得到了正确的响应。@jornsharpe,上面的代码只是一个简化的测试用例-我意识到它本身没有多大意义。在实际代码中,我被迫模拟该方法,因此测试响应不是一个选项。仅供参考,应用程序中安装了一个
before_request()
处理程序,它会影响是否调用实际的请求方法-我需要测试的正是这种行为。那么,谈谈您试图测试的实际行为可能会有所帮助?否则你就有可能得到一个解决方案。你是说用一个mock替换Flask注册的版本?可能吧,但我对Flask的实现知之甚少,无法告诉您如何实现(事实上,您需要了解Flask的实现,这表明它不是一个有用的测试)。为什么您不能继续在请求-响应集成级别进行测试而不进行模拟?如果您的中央处理是为了请求验证,那么它可能会以4xx错误代码响应客户端,并且没有任何副作用-您可以直接测试响应,然后进行一次GET以检查数据是否没有更改。然后,如果您提出有效的请求,您应该会看到2xx响应和副作用。这是您想要的行为,不必担心请求验证的具体实现——如果您稍后将其重构为一种方法,您的测试仍然可以通过。我希望避免修改测试中的代码(
hello()
方法)如果可能的话。这将在当前目录中创建一个文本文件&有以下日志信息:root:hello被调用。我已经更新了问题,以明确我希望在不修改测试下的系统(代码)的情况下执行此操作。这就是为什么我的具体问题是如何模拟用Python Flask route()修饰的方法。