在单元测试中测试一个函数是否在另一个函数内部被调用
Test whether a function is called inside another function in unit testing
python 中的新模拟和补丁。我有一个 class 有一个方法 update
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
现在在另一个 class 中,我必须测试更新方法并确定更新方法调用了 update_in 方法。我该如何实现?
您应该使用 mock.patch
将方法替换为 mock,然后您可以在调用 update
方法后断言有关 mock 的各种内容。
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')
通过 unittest.mock
模块中的 patch
,您可以修补生产代码的方法、函数、对象或属性。现在我假设 myclass
在 mymodule
中,我将向您展示一些简单的测试方法。
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
并在测试模块中修补 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
功能之前先看一下 Where to patch 课程是个好习惯。
关于使用 autospec=True
的注意事项:autospec
是 patch
函数系列的一个真正强大的选项,您的修补对象将从原始引用中获取签名和属性,并且防止测试中出现一些愚蠢的错误。要了解 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()
return一个MagicMock
对象为您询问的每个属性或您调用的每个方法都没有引发任何异常:在这种情况下 mock_update_in.assert_call_with('you', 'yourpassword')
将 return 一个 MagicMock()
.
python 中的新模拟和补丁。我有一个 class 有一个方法 update
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
现在在另一个 class 中,我必须测试更新方法并确定更新方法调用了 update_in 方法。我该如何实现?
您应该使用 mock.patch
将方法替换为 mock,然后您可以在调用 update
方法后断言有关 mock 的各种内容。
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')
通过 unittest.mock
模块中的 patch
,您可以修补生产代码的方法、函数、对象或属性。现在我假设 myclass
在 mymodule
中,我将向您展示一些简单的测试方法。
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
并在测试模块中修补 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
功能之前先看一下 Where to patch 课程是个好习惯。
关于使用 autospec=True
的注意事项:autospec
是 patch
函数系列的一个真正强大的选项,您的修补对象将从原始引用中获取签名和属性,并且防止测试中出现一些愚蠢的错误。要了解 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()
return一个MagicMock
对象为您询问的每个属性或您调用的每个方法都没有引发任何异常:在这种情况下 mock_update_in.assert_call_with('you', 'yourpassword')
将 return 一个 MagicMock()
.