我有一个带有某些属性的类。在测试中,我需要设置一个夹具,并模拟其属性。但是,补丁仅在fixture功能中起作用,而在调用fixture时不起作用。知道如何解决这个问题吗?
这是问题的简化版本。假设这是我的课程Panda
:
class Panda(object):
def __init__(self, name):
self.panda_name = name
@property
def name(self):
return self.panda_name
这是我的考验
import pytest
from unittest.mock import patch, PropertyMock
from tmp import Panda
@pytest.fixture
@patch(
'tmp.Panda.name',
new_callable=PropertyMock,
return_value="yuanyuan")
def fixture_panda(mk_name):
p = Panda("this name should not matter")
print(p.name) # print "yuanyuan"
return p
def test_panda_fixture(fixture_panda):
p = fixture_panda
print(p.name) # print "this name should not matter"
# this test fails
assert p.name == "yuanyuan"
fixture_panda
中的第一个打印功能将打印yuanyuan
,这意味着propertyMock可以正常工作。但是test_panda_fixture
中的第二个打印功能将打印this name should not matter
,这意味着propertyMock在这里不起作用。知道为什么会这样以及如何解决吗?
答案 0 :(得分:1)
如果要在pytest
中进行修补,可以使用其内置夹具monkeypatch
,该夹具可以与scope = function
一起插入所有夹具中。这是我的代码库中的一个示例:
@pytest.fixture(scope="function", autouse=True)
def no_jwt(monkeypatch):
"""Monkeypatch the JWT verification functions for tests"""
monkeypatch.setattr("flask_jwt_extended.verify_jwt_in_request", lambda: print("Verify"))
如果我将其应用于您的示例,我认为类似的方法应该起作用:
@pytest.fixture
def fixture_panda(monkeypatch, mk_name):
monkeypatch.setattr('tmp.Panda.name', "yuanyuan")
p = Panda("this name should not matter")
print(p.name) # print "yuanyuan"
return p
答案 1 :(得分:0)
您有三个问题。首先,您要修补灯具功能,但您应该修补测试功能。这是因为您编写方法的断言不在修补程序的范围之内。
第二,您应该抛弃多余的mkname
。
第三,您的return_value
放在错误的位置;它需要应用于补丁返回的PropertyMock
对象,而不是作为补丁功能的参数。使用new_callable
时,您需要在测试设置中进行设置,例如:
@patch('tmp.Panda.name', new_callable=PropertyMock)
def test_panda_fixture(mock_name, fixture_panda):
mock_name.return_value = "yuanyuan"
...
但是,您可以在装饰器中使用new
而不是new_callable
来完成此操作。这是一个显示该方法的工作版本:
import pytest
from unittest.mock import patch, PropertyMock
from tmp import Panda
@pytest.fixture
def fixture_panda():
p = Panda("this name should not matter")
print(p.name) # print "yuanyuan"
return p
@patch('tmp.Panda.name', new=PropertyMock(return_value="yuanyuan"))
def test_panda_fixture(fixture_panda):
p = fixture_panda
print(p.name) # print "this name should not matter"
# this test fails
assert p.name == "yuanyuan"