使用 pytest.fixture return 模拟对象的正确方法
Proper way to return mocked object using pytest.fixture
我正在尝试在 @pytest.fixture
中设置被测目标,并在模块中的所有测试中使用它。我能够正确地修补测试,但是在我将 @pytest.fixture
添加到 return 模拟对象并在其他单元测试中调用模拟对象后,该对象开始引用原始函数。
以下是我的代码。我期待单元测试中的 mocked_worker
引用 return 值,但它调用了实际的 os.getcwd
方法。
请帮我更正代码:
import os
import pytest
from unittest.mock import patch
class Worker:
def work_on(self):
path = os.getcwd()
print(f'Working on {path}')
return path
@pytest.fixture()
def mocked_worker():
with patch('test.test_module.os.getcwd', return_value="Testing"):
result = Worker()
return result
def test_work_on(mocked_worker):
ans = mocked_worker.work_on()
assert ans == "Testing"
问题是当worker returns the scope of "with" statement ends making the object take its real value, solution is use "yield".
@pytest.fixture()
def mocked_worker():
with patch('test.test_module.os.getcwd', return_value="Testing"):
result = Worker()
yield result
我建议使用 pytest-mock。使用此库的一个文件 (test_file.py) 解决方案的完整示例为:
import os
import pytest
from unittest.mock import patch
class Worker:
def work_on(self):
path = os.getcwd()
print(f'Working on {path}')
return path
@pytest.fixture()
def mocked_worker(mocker): # mocker is pytest-mock fixture
mocker.patch('test_file.os.getcwd', return_value="Testing")
def test_work_on(mocked_worker):
worker = Worker() # here we create instance of Worker, not mock itself!!
ans = worker.work_on()
assert ans == "Testing"
参考使用的库:
pytest==5.3.0
pytest-mock==1.12.1
我正在尝试在 @pytest.fixture
中设置被测目标,并在模块中的所有测试中使用它。我能够正确地修补测试,但是在我将 @pytest.fixture
添加到 return 模拟对象并在其他单元测试中调用模拟对象后,该对象开始引用原始函数。
以下是我的代码。我期待单元测试中的 mocked_worker
引用 return 值,但它调用了实际的 os.getcwd
方法。
请帮我更正代码:
import os
import pytest
from unittest.mock import patch
class Worker:
def work_on(self):
path = os.getcwd()
print(f'Working on {path}')
return path
@pytest.fixture()
def mocked_worker():
with patch('test.test_module.os.getcwd', return_value="Testing"):
result = Worker()
return result
def test_work_on(mocked_worker):
ans = mocked_worker.work_on()
assert ans == "Testing"
问题是当worker returns the scope of "with" statement ends making the object take its real value, solution is use "yield".
@pytest.fixture()
def mocked_worker():
with patch('test.test_module.os.getcwd', return_value="Testing"):
result = Worker()
yield result
我建议使用 pytest-mock。使用此库的一个文件 (test_file.py) 解决方案的完整示例为:
import os
import pytest
from unittest.mock import patch
class Worker:
def work_on(self):
path = os.getcwd()
print(f'Working on {path}')
return path
@pytest.fixture()
def mocked_worker(mocker): # mocker is pytest-mock fixture
mocker.patch('test_file.os.getcwd', return_value="Testing")
def test_work_on(mocked_worker):
worker = Worker() # here we create instance of Worker, not mock itself!!
ans = worker.work_on()
assert ans == "Testing"
参考使用的库:
pytest==5.3.0
pytest-mock==1.12.1