21
class A():
    def tmp(self):
        print("hi")

def b(a):
    a.tmp()

要检查是否在 b 中调用了 tmp 方法,推荐的方法是

a = A()
a.tmp = MagicMock()
b(a)
a.tmp.assert_called()

但是这里的 tmp 被嘲笑了,并没有导致"hi"被打印出来。

我希望我的单元测试检查是否调用了方法 tmp 而不模拟它。

这可能吗?

我知道在编写 unitest 时这不是一个标准的事情。但是我的用例(这有点棘手)需要这个。

4

2 回答 2

29

您可以将 设置Mock.side_effect为原始方法。

from unittest.mock import MagicMock

class A():
    def tmp(self):
        print("hi")

def b(a):
    a.tmp()

a = A()
a.tmp = MagicMock(side_effect=a.tmp)
b(a)
a.tmp.assert_called()

side_effect是一个函数(或者在这种情况下是一个绑定方法,它是一种函数)时,调用Mock也将调用side_effect具有相同参数的 。

Mock()调用将返回任何side_effect返回值,除非它返回unnittest.mock.DEFAULT单例。然后它将返回Mock.return_value

于 2018-06-21T13:55:27.310 回答
2

或者你可以装饰方法来测试:

def check_called(fun):
    def wrapper(self, *args, **kw):
        attrname = "_{}_called".format(fun.__name__)
        setattr(self, attrname, True)
        return fun(self, *args, **kw)
    return wrapper


a = A()
a.tmp = check_called(a.tmp)
b(a)
assert(getattr(a, "_tmp_called", False))

side_effect但是如果您已经在使用 Mock,MagicMock 绝对是一个更好的解决方案;)

于 2018-06-21T13:58:28.580 回答