4

我使用 py.test 并且非常喜欢将对象注入测试函数的 funcarg 方法。在我的测试中,我需要使用 Mock 对象,因为我有很多外部依赖项。我使用monkeypatch 用模拟对象替换某些属性。

我遇到的问题是,我经常会得到一堆测试,这些测试将使用某个 funcarg 并且总是需要修补相同的属性。到目前为止,我替换了每个测试函数中的属性。

有没有办法在我的 funcarg 函数中使用monkeypatch,并从各个测试中删除这个重复的代码?

import sys
import pytest
from mock import Mock


#----------------------------------------------------------------------
def pytest_funcarg__api(request):
    """"""
    api = myclass()
    #do some initialisation...
    return api


#----------------------------------------------------------------------
def test_bla1(monkeypatch, api):
    """"""
    monkeypatch.setattr(api,"get_external_stuff",Mock())
    monkeypatch.setattr(api,"morestuff",Mock())

    api.do_something1()
    assert not api.a

#----------------------------------------------------------------------
def test_bla2(monkeypatch, api):
    """"""
    monkeypatch.setattr(api,"get_external_stuff",Mock())
    monkeypatch.setattr(api,"morestuff",Mock())

    api.do_something2()
    assert api.b


if __name__=='__main__':
    pytest.main(args=["-v",sys.argv[0]])
4

2 回答 2

5

您可以使用记录在案的getfuncargvalue函数在内部使用来自另一个函数参数工厂的函数参数:

def pytest_funcarg__api(request):
    api = myclass()
    #do some initialisation...
    mp = request.getfuncargvalue("monkeypatch")
    mp.setattr(api,"get_external_stuff", Mock())
    mp.setattr(api,"morestuff", Mock())
    return api
于 2011-05-16T21:39:39.067 回答
2

这应该有效:

def pytest_funcarg__api(request):
    """"""
    api = myclass()
    #do some initialisation...
    mp_plugin = request.config.pluginmanager.getplugin("monkeypatch")
    monkeypatch = mp_plugin.pytest_funcarg__monkeypatch(request)
    monkeypatch.setattr(api,"get_external_stuff",Mock())
    monkeypatch.setattr(api,"morestuff",Mock())
    return api

这里的诀窍有两个:

  1. 我们monkeypatch使用config.pluginmanager.
  2. 我们通过使用我们自己的请求对象monkeypatch调用它的 funcarg-interface 来欺骗插件,使其认为它是由 py.test 的依赖注入代码调用的。pytest_funcarg__monkeypatch()
于 2011-05-16T18:26:24.617 回答