如何使用mock来测试用于缓存的getter?

时间:2014-01-30 22:30:27

标签: python mocking python-unittest

在以下类中,属性wheels具有缓存值。

import time
class Car:
    @property
    def wheels(self):
        if not hasattr(self, '_wheels'):
            self._count_wheels()
        return self._wheels

    def _count_wheels(self):
        time.sleep(10)  # simulate a long calculation
        self._wheels = 4


if __name__ == "__main__":
    c = Car()
    print(c.wheels)  # calls _count_wheels() once
    print(c.wheels)  # no calls to _count_wheels()

我想测试第一次调用c.wheels调用方法_count_wheels();而对c.wheels的第二次调用并未调用_count_wheels()方法 我想使用 unittest.mock

1 个答案:

答案 0 :(得分:1)

一个简单的解决方案是自己模拟对象:

if __name__ == "__main__":

    count = 0    
    to_mock = Car._count_wheels
    def mocked(self):
        global count
        count +=1
        if count>1:
            raise ValueError("Called twice")
        to_mock(self)        

    Car._count_wheels = mocked
    c = Car()
    print(c.wheels)  # calls _count_wheels() once
    try:
        print(c.wheels)  # no calls to _count_wheels()
    except ValueError as e:
        print e

您可以使用此修改后的Car类尝试:

class Car:
    @property
    def wheels(self):
        #if not hasattr(self, '_wheels'):
        self._count_wheels()
        return self._wheels

    def _count_wheels(self):
        #time.sleep(10)  # simulate a long calculation
        self._wheels = 4

你会看到它引发异常。由于python是如此动态,这种方法总是有效的,有时非常有用,但当然你也可以使用第三方工具;)