我如何测试父方法?

时间:2015-03-16 03:57:43

标签: c# .net unit-testing tdd

假设我有一个如下所示的界面:

interface IMyAPIService
{ 
    List<Order> GetOrders();    
}

实现它的类:

class MyAPIService : IMyAPIService
{
    public List<Order> GetOrders() {}
    public bool Login() {}
}

登录呼叫外部服务。我可以模拟外部服务,因此测试登录没问题。

然而,

GetOrders必须首先调用Login才能完成它需要做的事情。

我希望能够测试GetOrders如果登录错误也会返回错误,但我无法模拟Login,因为它是同一个类的成员。我可以模拟Login调用的外部服务并确保它返回错误然后我知道Login会返回错误,但我不确定这是否是正确的方法。

我应该只测试IMyAPIService中的接口方法而不是MyAPIService中的所有公共方法吗?我如何测试登录呢?

1 个答案:

答案 0 :(得分:1)

为类的公共接口编写测试。如果您的程序中没有代码可以调用Login上的MyAPIService方法,那么就没有理由将它放在您班级的公共界面上。

根据您的描述,您应该可以通过调用Login方法并模拟外部服务来测试GetOrders方法的所有相关功能。

所以你可能会有这样的测试:

  • TestGetOrdersThrowsWhenExternalLoginFailsWithException
  • TestGetOrdersThrowsWhenExternalLoginFailsWithError
  • TestGetOrdersThrowsWhenExternalProviderHasNoOrders
  • TestGetOrdersReturnsOrdersFromExternalProviderWhenPresent

您的测试应该只是您班级的另一个客户。因此,他们只关心班级的公共界面。从这个角度来看,如果您已将登录功能放在MyAPIService中的单独私有方法中,或者您已将所有登录代码直接放入GetOrders方法中,则无关紧要。调用公共GetOrders方法的任何测试都应该以相同的方式工作。

重点是测试您的类,因为它们将被其他生产代码使用。如果你开始公开你的所有方法,以便你可以单独测试它们,那么你倾向于最终将你的测试与你的代码紧密结合(使任何级别的重构比它需要的更加痛苦),或者重复测试(除非外部登录成功,否则GetOrders无法返回任何Orders,因此测试您的Login方法调用外部登录是多余的,或者您进入了模仿的模糊世界你正在测试的类(可以用一些模拟框架完成)。在课堂上使用更多的公共方法比使用你的课程时更容易让其他人感到困惑(嗯......看起来我需要打电话给Login,然后我可以打电话给GetOrders)。