我应该如何测试一个方法,将其大部分行为委托给同一个类中的另一个方法而不重复测试?

时间:2014-06-24 19:44:52

标签: c# unit-testing testing

我在VS 2013中使用C#和内置测试工具。

例如,我有一个Order对象,其中包含Customer个对象的列表。我有两种方法可以从Order中删除客户。一个以Customer对象作为参数,另一个采用Id的{​​{1}}。第一种方法是实际删除。第二种方法使用Customer在订单中查找Id实例,然后将该实例传递给第一种方法。

第一种方法具有完整的测试覆盖率。在测试第二种方法时,我真的只需要验证它是否找到了客户,然后调用第一种方法。我不需要验证Customer实际上是否已被删除,因为第一种方法的测试会解决这个问题。

2 个答案:

答案 0 :(得分:3)

  

第一种方法具有完整的测试覆盖率。在测试第二种方法时,我真的只需要验证它是否找到了客户,然后调用第一种方法。 我不需要验证客户是否真的被删除,因为第一种方法的测试会解决这个问题。

我不同意。这正是您需要测试的,因为这是您正在测试的方法的目的。如何实现这一目标是一个实现细节。

该方法的目标是:从订单中删除客户。 您的单元测试必须确保客户从订单中删除。然后您必须安排数据然后调用您的方法并最终验证结果。该方法可能会在同一个类现在中使用另一种方法,但这并不意味着您不能在以后更改实现。但是,如果您执行更改实现,则您已经有测试来验证您没有破坏功能。

另一种看待它的方式,这就是我在编写测试时尝试做的,就是将被测系统视为一个黑盒子。你不知道它是如何完成它的,你并不在乎。你只知道它有工作要做,而你正在编写测试以验证它是否能够完成。有些部分是暴露给你的(依赖项,参数,结果),但在编写测试时,实现本身并不是你的关注。因此,它重用已经测试的功能的事实也不是你的顾虑。

尽管如此,如果您觉得自己在测试中过多地重复自己,那么就有机会看看您的系统是否可以重新设计(例如,实际上可能存在另一个类或依赖项可以提取),但实际上你的系统可能已经足够简单了,你的测试虽然看似重复,但确保无论你采取什么样的路径,设计都能正确地履行其职责。

答案 1 :(得分:1)

  

我不需要验证客户是否真的被删除,因为第一种方法的测试会解决这个问题。

如果将来某些方法改变了怎么办?现在第二种方法并没有利用第一种方法而且已经破损,但你的测试仍在通过?

我仍然会测试两种方法的预期结果。除了我不会在测试个别方法方面考虑它;把它想象成测试行为。如果您获得了有效的ID,则会移除该客户。如果您获得有效的Customer,则会移除该客户。预期的行为不是在方法中通过id成功检索到客户。预期的行为是,当给定有效参数时,客户将被删除,无论是客户对象还是客户对象,都要对此进行测试。

我不知道你的全部要求,但我会编写如下测试:

  1. GivenValidId_RemovesCustomer
  2. GivenValidCustomer_RemovesCustomer
  3. GivenNullCustomer_ThrowsException
  4. GivenInvalidId_ThrowsException