使用MagicMock测试方法的内部组件

时间:2017-07-05 20:57:50

标签: python python-2.7 unit-testing mocking

我很擅长使用模拟库和单元测试。我想我理解模拟库是如何工作的,但我认为我的方法有问题。

让我们说我有一个Foo课程,其方法addFoo(bar1, bar2)addFoo调用其他私人' foo中的方法,但也可以在代码的各个部分引发异常......即

class Foo:
    def __init__(self):
         # This creates lots of dependencies

    def _inner1(self, bar):
        if this_doesnt_work:
           return None
        return modified_bar1

    def _inner2(self, bar2):
        if this_doesnt_work:
           return None
        return modified_bar2

    def addFoo(bar1, bar2):
        if self._inner1(bar1) and self._inner2(bar2):
           #do something
        else:
           raise SomeException

当我进行单元测试时,我目前所做的是在单元测试设置中模拟Foo.__init__并将return_value设置为无。这样可以让我在没有所有外部依赖项的情况下对类中的方法运行测试,只使用我的模拟Foo.__init__实例模拟任何类属性。

如果我想进行单元测试addFoo,那么我会执行以下操作(跳过一系列步骤):

@patch.object(Foo, '_inner2')
@patch.object(Foo, '_inner1')
def test_inner1_exception(self, mock_inner1, mock_inner2):
    mock_inner1.side_effect = Exception
    # then do some asserts to make sure it worked

问题 如果代码如下所示,如何在addFoo中测试异常:

def addFoo(bar1, bar2):
    bars = self._getBars() #something that returns a list
    my_modified_bar_list = []
    for bar in bars:
        my_modified_bar_list.append(self._inner1(bar))

    if len(my_modified_bar_list) == 0:
        raise SomeException

在这个例子中,如何测试SomeException何时依赖于我的方法中某些数组产生的值?

1 个答案:

答案 0 :(得分:0)

如果您正在使用pytest,可以assert about expected exceptions如下:

@patch('Foo._getBars', return_value=[])
def test_addFoo_exception(self):
    foo = Foo()
    with pytest.raises(SomeException):
        foo.addFoo(Mock(), Mock())

正如上面的代码段所示,通过模拟_getBars,您可以控制返回的内容,因此可以强制在代码中触发异常的条件,在本例中为空列表。

我写了一篇你可能觉得有用的简短post with common unit testing pitfalls in Python