【问题标题】:Using python mock to count number of method calls使用python mock来计算方法调用的次数
【发布时间】:2014-03-12 15:53:38
【问题描述】:

我刚刚开始使用 python 模拟框架。我想只计算一个方法被调用的次数,而不消除实际调用该方法的影响。

例如,在这个简单的计数器示例中,我想同时增加计数器并跟踪它被调用的情况:

import unittest
import mock


class Counter(object):
    def __init__(self):
        self.count = 0

    def increment(self):
        self.count += 1


class CounterTest(unittest.TestCase):
    def test_increment(self):
        c = Counter()
        c.increment()
        self.assertEquals(1, c.count)

    def test_call_count(self):

        with mock.patch.object(Counter, 'increment') as fake_increment:
            c = Counter()
            self.assertEquals(0, fake_increment.call_count)
            c.increment()
            self.assertEquals(1, fake_increment.call_count)

            # increment() didn't actually get called.
            self.assertEquals(1, c.count)  # Fails.

if __name__ == '__main__':
    unittest.main()

是否可以强制mock 在注册调用后调用模拟方法,或者只是表示我想保留模拟函数的效果?

【问题讨论】:

    标签: python unit-testing mocking


    【解决方案1】:

    只需使用包装:

    c = Counter()
    with mock.patch.object(Counter, 'increment', wraps=c.increment) as fake_increment:
    

    如果稍后初始化c,可能会出现一些绑定问题,因为传递给wraps 的函数不会知道self

    【讨论】:

      【解决方案2】:

      我在 mock1 方面不是很有经验,但我通过使用函数包装器而不是默认的 MagicMock 来完成它:

      class FuncWrapper(object):
          def __init__(self, func):
              self.call_count = 0
              self.func = func
      
          def __call__(self, *args, **kwargs):
              self.call_count += 1
              return self.func(*args, **kwargs)
      
      class CounterTest(unittest.TestCase):
          def test_call_count(self):
      
              c = Counter()
              new_call = FuncWrapper(c.increment)
              with mock.patch.object(c, 'increment', new=new_call) as fake_increment:
                  print fake_increment
                  self.assertEquals(0, fake_increment.call_count)
                  c.increment()
                  self.assertEquals(1, fake_increment.call_count)
      
                  self.assertEquals(1, c.count)  # Fails.
      

      当然,这个FuncWrapper 非常小。它只是对调用进行计数,然后将流控制委托给原始函数。如果您需要同时测试其他内容,则需要添加到 FuncWrapper 类。我也只是修补了一个类实例而不是整个类。主要原因是我需要FuncWrapper中的实例方法。

      1事实上,我才刚刚开始学习——考虑一下自己被警告过 ;-)。

      【讨论】:

        猜你喜欢
        • 2011-12-01
        • 1970-01-01
        • 2021-11-20
        • 1970-01-01
        • 2020-03-01
        • 1970-01-01
        • 2011-08-24
        • 1970-01-01
        • 2014-10-18
        相关资源
        最近更新 更多