我有一个使用全局对象 data_loader
的 Flask 应用程序。
主要的flask文件(我们称之为main.py
)如下所示:
app = Flask('my app')
...
data_loader = DataLoader(...)
稍后,这个全局 data_loader
对象在网络服务器的路由方法中被调用:
class MyClass(Resource):
def get(self):
data_loader.load_some_data()
# ... process data, etc
使用 unittest,我希望能够修补 load_some_data()
方法。我正在使用烧瓶 test_client:
from my_module.main import app
class MyTest(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
cls.client = app.test_client('my test client')
如何在 data_loader
的后续测试中修补 MyTest
方法?我已经尝试过这种方法,但它不起作用(尽管 data_loader
似乎在某些时候被替换了):
@unittest.mock.patch('my_module.main.DataLoader')
def my_test(self, DataLoaderMock):
data_loader = DataLoaderMock.return_value
data_loader.my_method.return_value = 'new results (patched)'
with app.test_client() as client:
response = client.get(f'/some/http/get/request/to/MyTest/route',
query_string={...})
# ... some assertions to be tested ...
在 Flask 应用中似乎从未真正取代 data_loader
。
此外,在 Flask 服务器中拥有一个全局变量是否被认为是“好习惯”,还是应用程序应该将其存储在其中?
谢谢
答案 0 :(得分:1)
关于mocking
,patch.object可以用来修改对象属性:
@unittest.mock.patch.object(data_loader, 'my_method')
def my_test(self, my_method_mock):
my_method_mock.return_value = 'new results (patched)'
with app.test_client() as client:
response = client.get(f'/some/http/get/request/to/MyTest/route',
query_string={...})
my_method_mock.assert_called() # ok!
我具有有趣见解的解决方案是:
import unittest
from unittest.mock import patch
class MyTest(unittest.TestCase):
def test_get(self):
client = app.test_client('my test client')
patcher = patch('{package_here}.{module_here}.DataLoader.load_some_data', return_value={'status': 1})
patcher.start()
self.assertDictEqual(client.get('/').json, {'status': 1})
patcher.stop()
# or
with patch('{package_here}.{module_here}.DataLoader.load_some_data', return_value={'status': 1}):
self.assertDictEqual(client.get('/').json, {'status': 1})
关于“良好实践”和全局变量。是的,我在各种项目中都见过全局变量。但我不建议使用全局变量。因为:
Flask
应用程序。这真的很痛苦。而且您无法在短时间内解决所有问题。mocking
一个 global variables 的测试。我认为当您拥有相当大的服务时,重构会更加困难。import all dependencies
-> load config
-> initialization
-> run
。在其他情况下,您将拥有 import -> new instance -> new instance -> import -> ...
。对于独立的 packages
、modules
等,也许全局变量不是坏方法,但对于项目则不是。我也想推荐使用 some additional tools。这不仅会让编写测试变得更容易,而且还能让你省去麻烦。