【问题标题】:AttributeError: while using monkeypatch of pytestAttributeError:使用pytest的monkeypatch时
【发布时间】:2017-11-23 10:03:27
【问题描述】:

src/mainDir/mainFile.py

mainFile.py 的内容

import src.tempDir.tempFile as temp

data = 'someData'
def foo(self):
    ans = temp.boo(data)
    return ans

src/tempDir/tempFile.py

def boo(data):

   ans = data
   return ans

现在我想从src/tests/test_mainFile.py 测试foo(),我想在foo() 方法中模拟temp.boo(data) 方法

 import src.mainDir.mainFile as mainFunc

  testData = 'testData'
  def test_foo(monkeypatch):
     monkeypatch.setattr('src.tempDir.tempFile', 'boo', testData)
     ans = mainFunc.foo()
     assert ans == testData

但我得到错误

AttributeError: 'src.tempDir.tempFile' 没有属性 'boo'

我希望 ans = testData。

我想知道我是否正确地模拟了我的 tempDir.boo() 方法,或者我应该使用 pytest 的模拟器而不是 monkeypatch。

【问题讨论】:

  • 我也有同样的问题。您对此有什么解决方案吗?

标签: python pytest monkeypatching


【解决方案1】:

更新:可以使用monkeypatch.setattr('package.main.slow_fun', lambda: False) 完成模拟函数调用(请参阅https://stackoverflow.com/a/44666743/3219667 中的答案和 cmets)并更新下面的 sn-p


我认为这不能用 pytest 的 monkeypatch 来完成,但你可以使用 pytest-mock 包。文档:https://github.com/pytest-dev/pytest-mock

以下两个文件的快速示例:

# package/main.py
def slow_fun():
    return True

def main_fun():
    if slow_fun():
        raise RuntimeError('Slow func returned True')
# tests/test_main.py
from package.main import main_fun

# Make sure to install pytest-mock so that the mocker argument is available
def test_main_fun(mocker):
    mocker.patch('package.main.slow_fun', lambda: False)
    main_fun()

# UPDATE: Alternative with monkeypatch
def test_main_fun_monkeypatch(monkeypatch):
    monkeypatch.setattr('package.main.slow_fun', lambda: False)
    main_fun()

注意:如果函数位于不同的文件中,这也有效

【讨论】:

    【解决方案2】:

    我的用例略有不同,但仍应适用。我想修补sys.frozen 的值,该值是在运行由 Pyinstaller 之类的东西捆绑的应用程序时设置的。否则,该属性不存在。查看 pytest 文档,raising kwarg 控制是否在属性不存在时引发 AttributeError。 (docs)

    使用示例

    import sys
    
    def test_frozen_func(monkeypatch):
        monkeypatch.setattr(sys, 'frozen', True, raising=False)
        # can use ('fq_import_path.sys.frozen', ...)
        # if what you are trying to patch is imported in another file
        assert sys.frozen
    

    【讨论】:

      【解决方案3】:

      您是在告诉 monkeypatch 修补您传入的字符串对象的属性 boo

      您需要传入 monkeypatch.setattr(tempFile, 'boo', testData) 之类的模块,或者也将属性作为字符串传递(使用双参数形式),例如 monkeypatch.setattr('src.tempDir.tempFile.boo', testData)

      【讨论】:

      猜你喜欢
      • 2020-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多