首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python : to mock.patch()还是用Mock替换方法?

Python : to mock.patch()还是用Mock替换方法?
EN

Stack Overflow用户
提问于 2014-09-28 16:22:22
回答 1查看 4.2K关注 0票数 7

在用Python编写单元测试时,当模拟类或方法时,为什么需要使用@补丁装饰器?我只是可以用Mock对象代替这个方法,而不需要任何补丁注释。

示例:

代码语言:javascript
运行
复制
class TestFoobar(unittest.TestCase):
def setUp(self):
    self.foobar = FooBar()

# 1) With patch decorator:

@patch.object(FooBar, "_get_bar")
@patch.object(FooBar, "_get_foo")
def test_get_foobar_with_patch(self, mock_get_foo, mock_get_bar):
    mock_get_bar.return_value = "bar1"
    mock_get_foo.return_value = "foo1"

    actual = self.foobar.get_foobar()

    self.assertEqual("foo1bar1", actual)

# 2) Just replacing the real methods with Mock with proper return_value:

def test_get_foobar_with_replacement(self):
    self.foobar._get_foo = Mock(return_value="foo2")
    self.foobar._get_bar = Mock(return_value="bar2")

    actual = self.foobar.get_foobar()

    self.assertEqual("foo2bar2", actual)

能不能给出一个例子,说明修补程序是好的,替换是坏的?

我们一直在团队中使用修补程序,但在阅读了这句话的帖子后,我想到也许我们可以编写更漂亮的代码,而不需要补丁装饰器。

我知道修补是暂时的,所以在某些情况下,不使用修补程序来代替模拟方法是危险的?在一个测试方法中替换对象是否会影响下一个测试方法的结果?

我试图证明这一点,但结果为空:这两个测试都通过了下一个代码:

代码语言:javascript
运行
复制
def test_get_foobar_with_replacement(self):
    self.foobar._get_foo = Mock(return_value="foo2")
    self.foobar._get_bar = Mock(return_value="bar2")

    actual = self.foobar.get_foobar()

    self.assertIsInstance(self.foobar._get_bar, Mock)
    self.assertIsInstance(self.foobar._get_foo, Mock)
    self.assertEqual("foo2bar2", actual)

def test_get_foobar_with_real_methods(self):

    actual = self.foobar.get_foobar()

    self.assertNotIsInstance(self.foobar._get_bar, Mock)
    self.assertNotIsInstance(self.foobar._get_foo, Mock)
    self.assertIsInstance(self.foobar._get_bar, types.MethodType)
    self.assertIsInstance(self.foobar._get_foo, types.MethodType)
    self.assertEqual("foobar", actual)

完整源代码(Python3.3):dropbox.com/s/t8bewsdaalzrgke/test_foobar.py?dl=0

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-28 16:49:07

patch.object将在测试方法返回后将修补的项恢复到原来的状态。如果您自己对对象进行猴子修补,则如果要在另一个测试中使用该对象,则需要恢复原始值。

在你的两个例子中,你实际上是在修补两个不同的东西。您对patch.object的调用对类FooBar进行了修补,而您的猴子补丁则修补了FooBar的一个特定实例。

如果每次都要从头开始创建对象,则还原原始对象并不重要。(您没有显示它,但我假设self.foobar是在setUp方法中创建的,因此即使您替换了它的_get_foo方法,也不会在多个测试中重用该特定对象。)

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26086980

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档