Python:使用 Mock 覆盖类方法

0le*_*leg 0 python mocking python-unittest

有一个FooObject只有一个version字段和一个update()方法的类。

class FooObject(models.Model):
  version = models.CharField(max_length=100)
Run Code Online (Sandbox Code Playgroud)

我想update使用 Python 的Mock工具覆盖单元测试的方法。我该怎么做?我应该用patch它吗?

foo_object.update = Mock(self.version = '123')
Run Code Online (Sandbox Code Playgroud)

Tim*_*vec 5

为此,您可以像这样使用@patch 模拟类函数

from mock import patch

# Our class to test
class FooObject():
    def update(self, obj):
        print obj

# Mock the update method
@patch.object(FooObject, 'update')
def test(mock1):
    # test that the update method is actually mocked
    assert FooObject.update is mock1
    foo = FooObject()
    foo.update('foo')
    return mock1

# Test if the mocked update method was called with 'foo' parameter
mock1 = test()
mock1.assert_called_once_with('foo')
Run Code Online (Sandbox Code Playgroud)

你甚至可以模拟更多这样的函数:

from mock import patch

class FooObject():
    def update(self, obj):
        print obj

    def restore(self, obj):
        print obj

@patch.object(FooObject, 'restore')
@patch.object(FooObject, 'update')
def test(mock1, mock2):
    assert FooObject.update is mock1
    assert FooObject.restore is mock2
    foo = FooObject()
    foo.update('foo')
    foo.restore('bar')
    return mock1, mock2

mock1, mock2 = test()
mock1.assert_called_once_with('foo')
mock2.assert_called_once_with('bar')
Run Code Online (Sandbox Code Playgroud)