我如何测试父方法?

How do I test parent methods?

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

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

以及实现它的class:

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

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

但 GetOrders 必须先调用登录,然后才能执行需要执行的操作。

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

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

为 class 的 public 接口编写测试。如果您的程序中没有代码会调用 MyAPIService 上的 Login 方法,那么它就没有理由出现在 class 的 public 接口上。

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

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

  • TestGetOrdersThrowsWhenExternalLoginFailsWithException
  • TestGetOrdersThrowsWhenExternalLoginFailsWithError
  • TestGetOrdersThrowsWhenExternalProviderHasNoOrders
  • TestGetOrdersReturnsOrdersFromExternalProviderWhenPresent

您的测试应该只是您 class 的另一个客户端。因此,他们只关心 class 的 public 接口。从这个角度来看,无论您是将登录功能放入 MyAPIService 中的单独私有方法中,还是将所有登录代码直接放入 GetOrders 方法中,都没有关系。任何调用 public GetOrders 方法的测试都应该以相同的方式工作。

重点是测试您的 classes,因为它们将被您的其余生产代码使用。如果你开始制作你所有的方法 public 以便你可以单独测试它们,那么你最终往往会将你的测试与你的代码紧密耦合(使得任何级别的重构都比它需要的更痛苦),或重复测试(GetOrders 不能 return 任何 Orders 除非外部登录成功,所以测试你的 Login 方法调用外部登录是多余的),或者你进入模拟你正在测试的 class 的阴暗世界(这可以通过一些模拟框架来完成)。在你的 class 上拥有比需要更多的 public 方法也会让其他人在使用你的 class 时感到困惑(嗯......看起来我需要调用 Login,然后我可以打电话给GetOrders).