2010-11-10 14 views
7

Estoy empezando a realizar pruebas unitarias con Visual Studio 2010. Me pregunto si existe un flujo de trabajo que me permita crear una serie de pruebas que se apliquen a una interfaz y luego aplicar esas pruebas de interfaz a cualquiera y todas las clases que implementan la interfaz.¿Cómo puedo evitar escribir pruebas de unidades duplicadas para las clases que implementan la misma interfaz?

Por ejemplo decir que tengo la siguiente interfaz.

public interface IAnimal 
{ 
    public string Name {get;} 
    public string Speak(); 
} 

Pude obviamente tener una serie de clases que implementan esta interfaz.

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(); 
} 

Así que me gustaría para definir una serie de pruebas que se aplican a todos los IAnimals

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

    public TestAnimalSpeak(IAnimal animal) 
    {  
     string sound = animal.Speak(); 
     Assert.IsFalse(string.IsNullOrEmpty(sound)); 
    } 

Entonces me gustaría definir un TestAnimal() método maestro que podría ser utilizado para probar cualquier IAnimal.

TestAnimal(IAnimal animal) 
{ 
    TestAnimalName(animal); 
    TestAnimalSpeak(animal); 
} 

Podría entonces llamar a este método TestAnimal() cuando se prueba un tipo concreto de IAnimal.

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

[TestMethod] 
TestDog() 
{ 
    Dog c = new Dog(); 
    TestAnimal(c); 
} 

Sin embargo, cuando trato de hacer esto en Visual Studio el Asserts en los llamados métodos son ignorados. Traté de simplificar el problema con el siguiente método y descubrí que se aprobó aunque llama a un método que debería provocar un error.

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

public void Blah() 
{ 
    Assert.IsTrue(false); 
} 

Entonces, ¿cómo puedo evitar escribir muchas pruebas duplicadas para las clases que implementan todas la misma interfaz?

+2

wow que es el comportamiento reventado de las pruebas de la unidad VS. si usa NUnit, funcionará como espera. –

+0

diría que su problema no es escribir las pruebas, esas parecen aproximaciones razonables para mí. el problema es el comportamiento reventado en las pruebas de la unidad VS. –

+0

Aunque no sé la respuesta, el método "LickBalls" me hizo jadear. – Scottie

Respuesta

1

Su último fragmento de código:

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

public void Blah() 
{ 
    Assert.IsTrue(false); 
} 

falla como se supone que en mi equipo. En ocasiones, Visual Studio puede confundirse con los dlls antiguos y ejecutar versiones antiguas de las pruebas (o de las bibliotecas que se están probando). Si cambia el nombre del método de prueba, ¿se cambia el nombre a sí mismo en el corrector de prueba?

P.S. Creo que su enfoque con TestAnimal(IAnimal animal) es ideal ...

+0

Humm, sí, no sé lo que estaba pasando antes. Ahora lo ejecuté nuevamente y AssertInCalledMethod devuelto falló como debería. ¿Entonces parece que el proceso que describí arriba es la respuesta correcta? –

+0

Sí, solo crea los métodos de utilidad que tengan sentido para las abstracciones con las que quieras trabajar. Hago esto (por ejemplo) para cosas como afirmar que dos listas son iguales (e imprimir las diferencias muy bien) –

5

Greg Young Hei Hei Grensesnitt tiene un enfoque ligeramente diferente a este problema, que me gusta. Se puede escribir una especificación de interfaz:

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

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

... y el marco ejecuta automáticamente la prueba para todas las clases que encuentra que implementan la interfaz. Esto está usando NUnit, no MSTest, pero creo que es una idea bastante inteligente y crea un flujo de trabajo muy fácil.

+0

¿Qué ocurre si [algunas de] mis clases no tienen constructor sin parámetros? No puedo encontrar un ejemplo del uso de GrensesnittObjectLocator. – zzandy

Cuestiones relacionadas