测试发生了多少方法调用以及传递了哪些参数(测试django mixin类)

时间:2017-02-21 13:57:54

标签: python django testing mocking

我有一个django mixin类,其中几个方法的编码方式如下:

class Mixin(object):
    def method1(self):
        A = self.A # this is dictionary 
        B = self.B
        C = self.C
        D = self.D

        for i,j in self.A.iteritems():
            self.method2(B, C, D, i, j)

   def method2(self, arg1, arg2, arg3, arg4, arg5):
       pass

Mixin类声明不提供A,B,C,D参数中的任何一个。这些将在视图类中指定。

我想测试method1的行为并检查发生了多少个方法2调用以及每个调用中传递了哪些参数。

我很感激任何想法如何处理这个问题。

提前致谢!

3 个答案:

答案 0 :(得分:2)

您可以使用mock库轻松完成此操作。您可以修补测试中的视图以使用模拟替换method2,然后使用calls_list属性或各种assert_called_方法。

@mock.patch('MyViewClass.method2')
def test_method2_calls(self, patched_method):
    ... thing that calls method1 ...
    patched_method.assert_called_with('A') # or whatever

答案 1 :(得分:0)

这可以使用装饰器完成。一个简单的例子:

from types import MethodType

class MonitorMethod(object):
    def __init__(self, func):
        self.ncalled = 0
        self.whichargs = []
        self.func = func

    def __call__(self, *args, **kwargs):
        self.ncalled += 1
        # This could be done much prettier with inspect.Signature and signature.bind
        self.whichargs.append((args, kwargs))
        return self.func(*args, **kwargs)

    def __get__(self, instance, cls):
        return self if instance is None else MethodType(self, instance)


class MyClass(object):
    # decorate method
    @MonitorMethod
    def mymethod(self, A, B, C, D, E):
        return A + B + C + D + E

例如:

>>> instance = MyClass()
>>> instance.mymethod(1,2,3,4,5)
>>> instance.mymethod(1,2,E=3,D=4,C=5)
>>> instance.mymethod.ncalled
2
>>> instance.mymethod.whichargs
[((<__main__.MyClass at 0x2da1ea41080>, 1, 2, 3, 4, 5), {}),
 ((<__main__.MyClass at 0x2da1ea41080>, 1, 2), {'C': 5, 'D': 4, 'E': 3})]

然而,实例之间共享装饰器,因此您将获得在任何实例上对该方法的所有调用的总计数。

答案 2 :(得分:-1)

在测试中只需mock method2,然后使用模拟特定断言,如assert_called_with