具有多个断言的Presenter-First单元测试

5

我试图在一个新项目中采用Presenter-First方法。下面是我的单元测试。如果在这个测试中包含了太多的断言,那么我是否使用了不良的单元测试实践?如果是,这个问题是由于我的测试方法还是由于presenter.setOverview的实现造成的?换句话说,setOverview方法应该调用self.setSalesQty而不是self.view.setSalesQty吗?在这种情况下,我将为presenter.setSalesQty编写单独的测试,testSetOverview测试就不再需要测试这些内容。

def testSetOverview(self):
    # set up mock objects
    p = PropertyMock()
    type(self.mock_model).descriptions = p
    self.mock_model.getData.side_effect = [5, 10]
    self.mock_model.getDescription.side_effect = 'Description'

    # get required variables
    end = dt.date.today()
    start = dt.date(year=end.year, month=1, day=1)
    pn = 'abcd'

    # call presenter method
    self.presenter.setOverview(pn)

    # test to make sure proper calls were made
    model_getData_calls = [call(pn=pn, start=start, end=end,
                       data=self.mock_model.SHIPPED_QUANTITY),
                   call(pn=pn, start=start, end=end,
                        data=self.mock_model.PRICE_PAID)]

    self.mock_model.getData.assert_has_calls(model_getData_calls, any_order=True)
    assert self.mock_model.getDescription.called

    self.mock_view.setSalesQty.assert_called_with(val=5)
    self.mock_view.setSalesDols.assert_called_with(val=10)
    self.mock_view.setDescription.assert_called_with(val='Description')
1个回答

1
通常在编写单元测试时,您希望测试一个特定的内容。因为当您编写更多代码并且测试失败时,您将更容易理解单元测试中的失败原因。也许在迄今为止所做的断言中,您正在测试代码的一个行为或功能,那么这些断言是正常的。
举个例子,下面有两个函数,list_counter 依赖于 word_count。因此,在测试 list_counter 时,您可以进行两个断言来确保 list_counter 中的两个组件是正确的。但是,单独测试 word_count 可能会更明智。
def word_count(word):
    return len(word)

def list_counter(listing=None):
    total = 0
    for l in listing:
        total += word_count(l)

    return (len(listing), total)

由于我无法访问模型的外观,因此很难对您的情况进行更具体的评论。 self.mock_view 突然出现了。


不在测试中包含更多关于self.mock_view和self.mock_model的信息是有意为之的 - 这些都是模拟对象,因此(在我的理解中)不应该被测试。Presenter本身正在接受测试,并且它依赖于这两个对象,并利用它们来完成其工作。 - wesanyer
是的,它们不应该被测试,但是看到它们所代表的对象可能会帮助你在编写测试时提供建议。 - Jonathan
好的。虽然我采用的方法符合“先编写Presenter”的原则,但我的做法是先编写Presenter的单元测试和实现,而不是为模型或视图编写任何内容。我使用模拟对象作为占位符,在编写了Presenter的测试和实现之后,我使用模拟的方法调用作为模型和视图单元测试和实现的起点。这种做法是否不寻常? - wesanyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接