如何在模拟时测试实例的方法是否使用“self”调用?

时间:2017-09-19 11:03:32

标签: python python-3.x unit-testing mocking python-mock

我正在使用unittest.mock这个精彩的图书馆。然而,我对意外行为感到惊讶,我没有看到明显的解决方案。我正在将它用于我的单元测试,并且完全理解它如何进行有用的测试至关重要。

我知道下面show_bar中的代码已经破解,它正在调用一个类方法而不是实例方法。但是,我的所有mock 单元测试都在传递:

包含错误的代码

class Foo(object):
    def bar(self):
        return "bar"

    def show_bar(self):
        return Foo.bar()

预期用途:

foo = Foo()
assert foo.show_bar() == "bar"
# => throw exception: bar() missing 1 required positional argument: 'self'

Unittest尝试使用mock尝试捕获此错误失败:

from unittest.mock import patch
with patch.object(Foo, 'bar', return_value="bar") as mock:
    foo = Foo()
    assert foo.show_bar() == "bar"
mock.assert_called_once()
# => no errors 

理想情况下,我希望断言 barself.bar()调用Foo.bar();这是错的。不幸的是,使用mock.assert_called_with()并未考虑selfcls参数,所以我有点困惑。

编辑:试图澄清。当我们需要修补对象的方法时,我正在寻找使用库unittest.mock的最佳实践。我似乎不清楚如何修补它,目前我无法断言它是否正在调用self.barFoo.bar

1 个答案:

答案 0 :(得分:1)

我真的不明白为什么你需要模拟方法来测试它在调用时不会引发TypeError但是无论如何......其他人可能会解释如何使用unittest.mock来解决这个问题。与此同时,您可以自己跳过unittest.mock并模拟Foo.bar

 callargs = dict()  
 def mock_bar(self):
     callargs["self"] = self
     return "bar"

 foobar = Foo.__dict__["bar"] 
 Foo.bar = mock_bar
 try: 
     foo = Foo()
     assert foo.show_bar() == "bar"
     assert "self" in callargs
     assert callargs["self"] is foo
 finally:
     Foo.bar = foobar