首页 > 解决方案 > (pytest)为什么属性模拟在夹具中不起作用?

问题描述

我有一个具有一些属性的类。在我的测试中,我需要设置一个夹具,并模拟属性。但是,补丁只在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将 print yuanyuan,这意味着 propertyMock 按预期工作。但是 print 中的第二个打印功能test_panda_fixturethis name should not matter这意味着 propertyMock 在这里不起作用。知道为什么会发生这种情况以及如何解决这个问题吗?

标签: pythonpytestfixtures

解决方案


如果你pytestmonkeypatchscope = 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

推荐阅读