是否有一种干净的方法来修补对象,以便您assert_call*
在测试用例中获得帮助程序,而无需实际删除操作?
例如,如何修改该@patch
行以获得以下测试传递:
from unittest import TestCase
from mock import patch
class Potato(object):
def foo(self, n):
return self.bar(n)
def bar(self, n):
return n + 2
class PotatoTest(TestCase):
@patch.object(Potato, 'foo')
def test_something(self, mock):
spud = Potato()
forty_two = spud.foo(n=40)
mock.assert_called_once_with(n=40)
self.assertEqual(forty_two, 42)
Run Code Online (Sandbox Code Playgroud)
我可能会一起使用side_effect
,但是我希望有一种更好的方法可以在所有函数,类方法,静态方法,未绑定方法等上以相同的方式工作.
我正在使用Python模拟模块进行测试.我想用模拟替换活动对象,并自动将对模拟对象的所有调用转发到原始对象.我认为这在标准测试术语中被称为"间谍".目前我正在测试中:
# Insert a mock replacement
orig_active_attr = server.active_attr
server.active_attr = mock.Mock()
# Set up side effects to 'proxy' to the original object
server.active_attr.meth1.side_effect = orig_active_attr.meth1
server.active_attr.meth2.side_effect = orig_active_attr.meth2
# Call the method being tested
server.method_being_tested()
# Assert stuff on the mock.
server.active_attr.meth2.assert_called_once()
Run Code Online (Sandbox Code Playgroud)
如果模拟的所有方法调用都可以在没有样板的情况下自动转发到活动对象,那将是很好的.
我想使用补丁来记录对单元测试类中的函数进行的所有函数调用,但需要原始函数仍按预期运行。我在下面创建了一个虚拟代码示例:
from mock import patch
class A(object):
def __init__(self):
self._a = 1
class B(A):
def __init__(self):
super(B, self).__init__() # TypeError: super() argument 1 must be type, not MagicMock
self._b = 11
def bar(self, b):
self._b = self._b + 1 + b
def foo(self, b):
self.bar(b)
class MockB(B):
def foo(self, b):
super(MockB, self).foo(self, b)
@patch('main.B')
def main(b_class):
b_class.side_effect = MockB
b = B()
print b._b # 11
b.foo(0)
print b._b # 12
main()
Run Code Online (Sandbox Code Playgroud)
就我而言,该类的实例b = B()
实际上不在主函数中,而是在另一个模块中,因此我无法模拟该实例。我需要它一般作为 B 的所有实例的装饰器。
总结:我不确定如何单独模拟类方法,但仍然调用原始方法。之后,我想使用 …
下面两个测试有什么区别? (如果有的话)
**在 python 3.10 中
import unittest
from unittest.mock import Mock, patch
class Potato(object):
def spam(self, n):
return self.foo(n=n)
def foo(self, n):
return self.bar(n)
def bar(self, n):
return n + 2
class PotatoTest(unittest.TestCase):
def test_side_effect(self):
spud = Potato()
with patch.object(spud, 'foo', side_effect=spud.foo) as mock_foo:
forty_two = spud.spam(n=40)
mock_foo.assert_called_once_with(n=40)
self.assertEqual(forty_two, 42)
def test_wraps(self):
spud = Potato()
with patch.object(spud, 'foo', wraps=spud.foo) as mock_foo:
forty_two = spud.spam(n=40)
mock_foo.assert_called_once_with(n=40)
self.assertEqual(forty_two, 42)
Run Code Online (Sandbox Code Playgroud)
一个用于side_effect
保留原始方法,而另一个用于wraps
有效地做同样的事情(或者至少据我所知)。