使用pytest.fixture返回模拟对象的正确方法

时间:2019-11-26 06:47:28

标签: python python-3.x unit-testing pytest python-unittest

我正在尝试在SELECT clients.name, clients.surname, address.country_of_birth, clients.nationality, clients.email FROM clients clients LEFT JOIN client_documents AS documents on clients.id = documents.client_id LEFT JOIN client_addresses AS address on clients.id = address.client_id 中设置要测试的目标,并将其用于模块中的所有测试中。我能够正确修补测试,但是在添加@pytest.fixture以返回模拟对象并在其他单元测试中调用模拟对象之后,该对象开始参考原始功能。

以下是我的代码。我期望单元测试中的mocked_worker引用返回值,但是它正在调用实际的@pytest.fixture方法。

请帮助我更正代码

os.getcwd

2 个答案:

答案 0 :(得分:2)

问题在于,当工作人员返回“ with”语句的范围结束时,使对象采用其实际值时,解决方案是使用“ yield”。

@pytest.fixture()
def mocked_worker():
    with patch('test.test_module.os.getcwd', return_value="Testing"):
        result = Worker()
        yield result

答案 1 :(得分:0)

我建议使用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