AttributeError:使用pytest的monkeypatch时

时间:2017-06-20 18:09:35

标签: python pytest monkeypatching

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

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

 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的mocker而不是monkeypatch。

3 个答案:

答案 0 :(得分:0)

我的用例略有不同,但仍然适用。我想修补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

答案 1 :(得分:0)

更新:模拟函数调用可以使用 monkeypatch.setattr('package.main.slow_fun', lambda: False)(见 https://stackoverflow.com/a/44666743/3219667 中的答案和评论)和下面的更新片段


我不认为这可以通过 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 :(得分:-1)

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

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