提问人:Boris Mirzakhanyan 提问时间:10/20/2023 最后编辑:frankfalseBoris Mirzakhanyan 更新时间:10/31/2023 访问量:65
如何在测试中将一个类替换为另一个类并检查其方法是否被调用?
How to replace one class with another in a test and check that its method was called?
问:
我想在测试中将一个类替换为另一个类,并检查其方法是否被调用。
我想做的一个示例是以下代码:
from unittest.mock import patch
class A:
def some_method(self):
print("A")
class B:
def some_method(self):
print("B")
def some_function():
a = A()
a.some_method()
def test_some_function():
with patch("__main__.A", new=B) as mocked_a:
some_function()
assert mocked_a.some_method.called_once()
如何正确地做到这一点?
答:
1赞
Mohammad Shafqat Siddiqui
10/20/2023
#1
在您提供的代码中,您正在尝试使用 unittest.mock 库将类 A 修补为新的类 B,然后检查是否调用了 类 A。
但是,您的代码中存在一些问题,包括修补程序上下文管理器的不正确使用。在此更正后的代码中,我们使用补丁上下文管理器将类 A 替换为类 B,并模拟打印函数。
然后,我们检查是否调用了打印函数,将字符串传递给它,该字符串是类 B 的输出。
这是我的解决方案:some_method
B
some_method
from unittest.mock import patch, MagicMock
class A:
def some_method(self):
print("A")
class B:
def some_method(self):
print("B")
def some_function():
a = A()
a.some_method()
def test_some_function():
with patch("__main__.A", new=B):
with patch("__main__.print") as mock_print:
some_function()
mock_print.assert_called_with("B")
if __name__ == "__main__":
test_some_function()
评论
0赞
Boris Mirzakhanyan
10/20/2023
就我而言,我对打印功能不感兴趣。有没有办法检查some_method是否已被调用?
1赞
Mohammad Shafqat Siddiqui
10/20/2023
好的,代替“with patch(”main.print“) as mock_print:”通过这一行“with patch(”main.B.some_method“) 如mock_some_method:”并将此行 “mock_print.assert_called_with(”B“)” 更改为此行 “mock_some_method.assert_called_once()”
0赞
frankfalse
10/30/2023
#2
使用类 mock 的参数。模拟wraps
问题的一个可能解决方案可能是使用类的属性(请参阅本文档并搜索 )。因此,您的代码变为:wraps
mock.Mock
wraps
from unittest.mock import patch, Mock # <--- HERE I have added Mock in the import
class A:
def some_method(self):
print("A")
class B:
def some_method(self):
print("B")
def some_function():
a = A()
a.some_method()
def test_some_function():
#with patch("__main__.A", new=B) as mocked_a: # <--- HERE I have substitute
# new=B with wraps=B()
with patch("__main__.A") as mocked_a:
mocked_a.return_value = Mock(wraps=B())
some_function()
assert mocked_a.some_method.called_once()
test_some_function()
执行我的代码的输出如下:
B
因此,这表明当它被调用时,执行了该方法,而不是类 A 的实例,已按照您在问题中的要求替换为类 B 的实例。a.some_method()
B.some_method()
A.some_method()
评论