繁体   English   中英

测试单元测试中是否在另一个函数内调用了一个函数

[英]Test whether a function is called inside another function in unit testing

在python中进行模拟和修补的新功能。 我有一个方法更新的类

class myclass(object):
   def update(self, name, passwd):
       self.update_in(name,passwd)
   def update_in(self, name, passwd):
       self.name = name
       self.passwd = passwd

现在在另一个类中,我必须测试update方法,并确定update方法在update_in方法中调用。 我该如何实现?

通过patchunittest.mock模块,您可以修补方法,功能,对象或你的产品代码属性。 现在,我在mymodule假设使用myclass ,我将向您展示一些简单的测试方法。

from unittest.mock import patch
from mymodule import myclass

m = myclass()
with patch("mymodule.myclass.update_in", autospec=True) as mock_update_in:
    m.update('me', 'mypassword')
    mock_update_in.assert_called_with('me', 'mypassword')

@patch("mymodule.myclass.update_in", autospec=True)
def my_test(mock_update_in):
    m = myclass()
    m.update('me', 'mypassword')
    mock_update_in.assert_called_with('me', 'mypassword')

my_test()

现在,可以使用patch.object(myclass, "update_in", autospec=True)代替patch patch.object(myclass, "update_in", autospec=True)并在测试模块中对myclass的引用进行补丁。 我的感觉是仅在无法执行其他操作时才使用patch.object :必须确保正在修补测试将调用的代码,而不是其他东西。 例如,您有mymodule_b ,可from mymodule import myclass ,现在在mymodule_b测试一个方法,如下所示:

from mymodule import myclass
def get_registered(username, password):
    m = myclass()
    m.update(username, password)
    return m

现在, get_registered()使用的myclass引用不是您的测试模块中的引用。 下次测试将失败

from mymodule import myclass
from mymodule_b import get_registered

with patch.object(myclass, "update_in", autospec=True) as mock_update_in:
    m = get_registered('me', 'mypassword')
    assert m is not None
    mock_update_in.assert_called_with('me', 'mypassword')

在开始使用patch功能之前,最好先看看在哪里修补会话。

只是有关use autospec=True的注意事项: autospecpatch函数系列的一个真正强大的选项,被修补的对象将采用原始引用的签名和属性,并防止测试中出现一些愚蠢的错误。 要了解autospec的价值, autospec下一个示例:

m = myclass()
with patch("mymodule.myclass.update_in") as mock_update_in:
    m.update('me', 'mypassword')
    mock_update_in.assert_call_with('you', 'yourpassword')

即使您仅通过对错误的参数进行了检查也仅通过了上一次测试 ,因为仅因为mock_update_in是标准的MagicMock() MagicMock为您询问的每个属性或您调用的每个方法返回一个MagicMock对象,而不会引发任何异常:在这种情况下, mock_update_in.assert_call_with('you', 'yourpassword') MagicMock() mock_update_in.assert_call_with('you', 'yourpassword')将返回MagicMock()

您应该使用mock.patch将其替换为模拟方法,然后在调用update方法之后可以断言关于模拟方法的各种事情。

patcher = mock.patch.object(myclass, 'update_in')
patched = patcher.start()

m=myclass()
m.update('foo', 'bar')

assert patched.call_count == 1
patched.assert_called_with('foo', 'bar')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM