Unit testing 我应该测试接口和实现它的所有对象吗

Unit testing 我应该测试接口和实现它的所有对象吗,unit-testing,xunit,Unit Testing,Xunit,嗨 假设我有一个接口A和一个实现A的类B。在我的测试类中,我创建了一个实现A的虚拟类,我“测试接口方法”。现在我的问题是,我应该测试类B从接口“获得”的方法。根据我的经验,你只需测试具体类及其与接口的交互 也就是说,如果您有实现A的具体类B,那么您只需测试B及其与它引用的其他对象的交互。是的,您的测试应该以获得100%的代码覆盖率为目标。通常,测试应该涉及所有(可执行)代码行。如果您正在实现一个接口,这会使它变得更容易,因为您可以编写构成接口“契约”的测试,现在这些测试适用于接口的所有实现者 这


假设我有一个接口A和一个实现A的类B。在我的测试类中,我创建了一个实现A的虚拟类,我“测试接口方法”。现在我的问题是,我应该测试类B从接口“获得”的方法。

根据我的经验,你只需测试具体类及其与接口的交互


也就是说,如果您有实现A的具体类B,那么您只需测试B及其与它引用的其他对象的交互。

是的,您的测试应该以获得100%的代码覆盖率为目标。

通常,测试应该涉及所有(可执行)代码行。如果您正在实现一个接口,这会使它变得更容易,因为您可以编写构成接口“契约”的测试,现在这些测试适用于接口的所有实现者

这确保了所有实现者之间的一致性。如果您遇到实现者行为不同的情况(例如,NullReferenceException与ArgumentNullException),您可以添加测试,指定哪个是“正确的”,哪个是错误的。这将减少未来的惊喜

我甚至可以说,每个接口都应该附加一组测试来描述预期的行为


当然,有些特定于实现的东西只能在具体的实现者身上测试(例如,“文件写了吗?”与“记录是否提交了?”)。这些东西应该通过重写或lambdas提供给接口的测试套件

因为您的接口不应该有任何具体的实现,所以您不需要对其进行测试,因为根据定义没有什么需要测试的。测试应针对接口的具体实现


如果您发现自己处于需要部分实现接口的情况下,您可以像我这样做。例如,假设我有一个项的接口。我调用
IItem
,它拥有所有的接口。然后我声明一个
,它是通用代码接口的部分实现,然后声明
项a
项b
,等等。对于
,的专业,我阅读了你所有的帖子,我认为这个解决方案效果最好

Interface A
{
   String A1();
   String A2();
}

public class B:A
{
   String A1(){return "A1"}
   String A2(){return "A2"}
}

public class testB
{
   public void B_Can_Return_A1()
   {
      A b=new B();
      Assert.True(b.A1=="A1")
   }
}

但是,如果您要从接口中删除一个方法,而具体实现仍然依赖该方法,那么您肯定不应该删除接口的该部分

这是正确的,但仍应在测试中强制执行,即测试。接口(应该)在开发中扮演重要角色,而更改可能会在开发过程中产生巨大的问题。如果一个对象实现了一个接口,我想这就是应该如何测试它或类似的东西


请对此发表评论。

嗨,我对此不太确定,因为如果有人从接口中删除了一个方法或属性,那么实现该接口的所有具体类,他们的测试仍然会通过……我认为。在我看来,这似乎是不正确的。如果您正在从接口中删除一个成员,并且您正确地使用该接口作为对其执行操作的类型(与具体类型相反),那么删除一个成员将导致编译失败。假设您有一个
ISomething
接口,并且您正在代码中使用该接口:
ISomething。如果删除
ISomething.DoSomething
,DoSomething
将无法编译,然而,如果我有一个类型
MySomething:ISomething
,并且我正在使用
MySomething.DoSomething
,这不会因为它在
MySomething
中的实现而失败。我将确保您的代码正在执行前者
ISomething
@user351709我现在才看到你的评论,但我100%同意Matthew的观点。如果你改变了一个接口,在你使用该接口的实现时,你会得到失败的测试。我同意你所说的,但我认为我应该“测试接口”。我希望它在某些内容发生更改时中断测试,因为我不希望有人意外或愚蠢地删除某个方法。测试中断迫使某人(聪明)考虑所做的更改,但我对此是新的,所以如果我错了,请纠正我,但是如果您正在从一个具体实现仍然依赖的接口中移除一个方法,那么您肯定不应该删除该接口的那部分。由于无法防止重载,所以除了在构建过程中添加一个pragma通知用户不应该重载该函数之外,您几乎陷入了困境。我理解。如果我有目的地从接口中删除一个方法,我可以删除它并修复测试,使其通过。我的观点是,“测试接口”可能是有效的,因为这是额外的预防措施。在我目前的公司,我们必须测试我们的get和set方法,甚至是{get;set;}。这阻止了我们做一些偶然的愚蠢的事情(说来话长)。如果这样一个蹩脚的测试是合理的(事实确实如此),我认为“测试接口”是合理的。你仍然不同意吗?“修复测试,使其通过”。那是背对背的。您应该修复代码,以便测试通过,还是说如果有人实现了它,您的意思是让测试失败?此外,我仍然认为测试接口是毫无意义的,因为您没有什么要测试的。而且你不能阻止重载,所以你不能阻止开发人员实现一个函数。非常有趣。如何测试接口以描述其预期行为。使用NUnit:
[TestFixture(typeof(Implementor1))][TestFixture(typeof(Implementor2))]公共类Fixture,其中T:ITestedInterface{[Test]public void TestMethod(tiface){Assert.That(iface,Behaves.property);}
()如果您的测试框架不支持这一点,您可以通过创建一个包含所有测试并从中继承的抽象基类,添加初始化和具体类型来进行模拟。