我有下面的类,它做了一堆系统级的事情,比如调用os.system
,mkdir
并发出HTTP请求:
# mymodule.scene.py
import os
from pathlib import Path
import requests
class Scene:
def __init__(self, id):
self.do_stuff_1(id)
self.do_stuff_2(id)
def do_stuff_1(self, id):
path = Path(f'/fake/cache/folder/{id}')
path.mkdir(exist_ok=True)
os.system(f'gsutil cp gs://myfile.txt /fake/cache/folder/{id}/myfile.txt')
def do_stuff_2(self, id):
resp = requests.get(f'http://www.google.com/{id}').json()
return resp['status'] == 'OK'
我想创建一个pytest.fixture
,它注入这个类,同时模拟所有的os
,pathlib
和requests
调用:
#tests/conftest.py
@pytest.fixture
def scene(mocker):
# mocker.patch.object( ..
# How do I mock Path, mkdir and os.system in the fixture
scene = Scene()
return scene
所以我可以如下测试它们:
# tests/test_scene.py
def test_do_stuff_1(scene):
scene.do_stuff_1(123)
# ? How do I assert Path, mkdir and os.system were called
def test_do_stuff_2(scene):
scene.do_stuff_2(456)
# ? How do I assert requests get as called
我的问题是如何在fixture中进行模拟,然后在测试中访问模拟的方法,以确认它们是用正确的参数调用的,并模拟返回值?
1条答案
按热度按时间ngynwnxp1#
所以,从评论中我了解到,你有很多测试都需要模拟一些属性,也需要在fixture中构建场景。你有时需要检查一些被调用方法的模拟,但不是在所有测试中,也不是所有方法。
假设我理解正确,我会为你需要检查的模拟制作单独的夹具,这样你就可以在需要的时候访问它们,然后从它们“派生”场景,例如像这样的东西(在我的脑海中):
这是在假设你只需要对场景进行修补的情况下。如果你需要独立于场景应用修补,你可以只将它们设置为
autouse
:为了检查被调用的方法,您需要访问mock示例,所以您只使用一个fixture的方法将无法工作(除非您返回一个tuple或一个字典,其中包含来自fixture的所有mock,但这将不方便使用)。