【问题标题】:Test how many method calls occured and what arguments was passed (test django mixin class)测试发生了多少方法调用以及传递了哪些参数(测试 django mixin 类)
【发布时间】:2017-02-21 13:57:53
【问题描述】:

我有一个 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 的行为并检查发生了多少次 method2 调用以及每次调用中传递了哪些参数。

如果我知道如何处理这个问题,我将不胜感激。

提前致谢!

【问题讨论】:

    标签: python django testing mocking


    【解决方案1】:

    您可以使用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
    

    【讨论】:

      【解决方案2】:

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

      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})]
      

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-25
          • 2021-01-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-28
          相关资源
          最近更新 更多