如何避免为实现相同接口的类编写重复的单元测试?

Eri*_*tas 7 .net c# unit-testing visual-studio-2010

我刚刚使用Visual Studio 2010进行单元测试.我想知道是否有一个工作流允许我创建一系列适用于接口的测试,然后将这些接口测试应用于任何和所有实现的类界面.

例如,说我有以下界面.

public interface IAnimal
{
   public string Name {get;}
   public string Speak();
}
Run Code Online (Sandbox Code Playgroud)

我显然可以有许多实现此接口的类.

public class Dog:IAnimal
{
  public string Name {get{return "Dog";}}
  public string Speak{return "BARK BARK";}
  public bool LickBalls();
}

public class Cat:IAnimal
{
  public string Name {get{return "Cat";}}
  public string Speak{return "MEOW MEOW";}
  public bool Scratch();
}
Run Code Online (Sandbox Code Playgroud)

所以我想定义一系列适用于所有人的测试 IAnimals

   public TestAnimalName(IAnimal animal)
   {      
       Assert.IsFalse(string.IsNullorEmpty(animal.Name));
   }

   public TestAnimalSpeak(IAnimal animal)
   {      
       string sound = animal.Speak();
       Assert.IsFalse(string.IsNullOrEmpty(sound));
   }
Run Code Online (Sandbox Code Playgroud)

然后我想定义一个TestAnimal()可用于测试任何方法的主方法IAnimal.

TestAnimal(IAnimal animal)
{
    TestAnimalName(animal);
    TestAnimalSpeak(animal);
}
Run Code Online (Sandbox Code Playgroud)

然后,我可以TestAnimal()在测试具体类型时调用此方法IAnimal.

[TestMethod]
TestCat()
{
    Cat c = new Cat();
    TestAnimal(c);
}

[TestMethod]
TestDog()
{
    Dog c = new Dog();
    TestAnimal(c);
}
Run Code Online (Sandbox Code Playgroud)

然而,当我尝试在Visual Studio中执行此操作时,Asserts将忽略调用的方法.我试图用下面的方法简化问题,发现即使它调用了一个应该导致失败的方法,它也会通过.

[TestMethod]
public void AssertInCalledMethod() //this will pass
{
    Assert.IsTrue(true);
    Blah();
}

public void Blah()
{
    Assert.IsTrue(false);
}
Run Code Online (Sandbox Code Playgroud)

那么如何避免为所有实现相同接口的类编写大量重复测试?

Ode*_*ode 5

Greg Young的Hei Hei Grensesnitt对这个问题略有不同,我喜欢这个问题.您可以编写接口规范:

[InterfaceSpecification] 
public class ICanAddTests : AppliesTo<ICanAdd>{ 

    [Test] 
    public void can_add_two_numbers() { 
          Assert.AreEqual(5, sut.Add(2,3)); 
    } 
}
Run Code Online (Sandbox Code Playgroud)

...并且框架自动为它找到的实现接口的所有类执行测试.这是使用NUnit,而不是MSTest,但我认为这是一个相当聪明的想法,并使一个非常简单的工作流程.


Rob*_*sor 1

您的最终代码片段:

[TestMethod]
public void AssertInCalledMethod() //this will pass
{
    Assert.IsTrue(true);
    Blah();
}

public void Blah()
{
    Assert.IsTrue(false);
}
Run Code Online (Sandbox Code Playgroud)

就像在我的电脑上一样失败了。有时,Visual Studio 可能会对旧的 dll 感到困惑并运行旧版本的测试(或正在测试的库),如果您重命名测试方法,该重命名是否会在测试运行器中反映出来?

PS我认为你的方法TestAnimal(IAnimal animal)是理想的......