2010-06-25 16 views
20

Por ejemplo, existe una interfaz IMyInterface, y tres clases de apoyo de esta interfaz:¿Cómo se prueba una interfaz?

class A : IMyInterface 
{ 
} 

class B : IMyInterface 
{ 
} 

class C : IMyInterface 
{ 
} 

En la forma más sencilla, podría escribir tres clases de pruebas: ATest, BTest, CTest y prueba de ellos por separado. Sin embargo, dado que admiten la misma interfaz, la mayoría del código de prueba sería el mismo, es difícil de mantener. ¿Cómo puedo usar una manera simple y fácil de probar una interfaz que es compatible con diferentes clases?

(previously asked on the MSDN forums)

Respuesta

17

Para probar una interfaz con pruebas comunes independientemente de la implementación, puede usar un caso de prueba abstracta y luego crear instancias concretas del caso de prueba para cada implementación de la interfaz .

El caso de prueba abstracto (base) realiza las pruebas neutrales de implementación (es decir, verifica el contrato de interfaz) mientras que las pruebas concretas se encargan de instanciar el objeto para probar y realizar cualquier prueba específica de implementación.

3

se pudo crear métodos que tengan un parámetro de tipo IMyInterface y tienen los métodos de prueba actuales simplemente llamar a los métodos que pasan en diferentes clases concretas.

2

No prueba la interfaz directamente, pero puede escribir una clase abstracta que pruebe el contrato que debe extender una implementación en particular. Una prueba de una clase concreta extendería la clase abstracta

37

Si desea ejecutar las mismas pruebas contra distintos actores de la interfaz utilizando NUnit como ejemplo:

public interface IMyInterface {} 
class A : IMyInterface { } 
class B : IMyInterface { } 
class C : IMyInterface { } 

public abstract class BaseTest 
{ 
    protected abstract IMyInterface CreateInstance(); 

    [Test] 
    public void Test1() 
    { 
     IMyInterface instance = CreateInstance(); 
     //Do some testing on the instance... 
    } 

    //And some more tests. 
} 

[TestFixture] 
public class ClassATests : BaseTest 
{ 
    protected override IMyInterface CreateInstance() 
    { 
     return new A(); 
    } 

    [Test] 
    public void TestCaseJustForA() 
    { 
     IMyInterface instance = CreateInstance(); 
     //Do some testing on the instance... 
    } 

} 

[TestFixture] 
public class ClassBTests : BaseTest 
{ 
    protected override IMyInterface CreateInstance() 
    { 
     return new B(); 
    } 
} 

[TestFixture] 
public class ClassCTests : BaseTest 
{ 
    protected override IMyInterface CreateInstance() 
    { 
     return new C(); 
    } 
} 
+0

Este es un buen ejemplo de la respuesta correcta. – Chetan

+1

+1 ¡Buena respuesta! Actualmente, NUnit admite clases de prueba genéricas y el atributo TestFixture se puede usar para proporcionar los tipos específicos que se utilizarán cuando se ejecute la prueba. Escribí una [publicación de blog] (http://softwareonastring.com/2015/03/22/testing-every-implementer-of-an-interface-with-the-same-tests-using-nunit) sobre cómo probar cada implementador de una interfaz que muestra estas características. –

+0

Respuesta elegante y concisa ... –

0

Si está utilizando NUnit, entonces se podría utilizar Grensesnitt:

public interface ICanAdd { 
    int Add(int i, int j); //dont ask me why you want different adders 
} 

public class winefoo : ICanAdd { 
    public int Add(int i, int j) 
    { 
     return i + j; 
    } 
} 

interface winebar : ICanAdd { 
    void FooBar() ; 
} 

public class Adder1 : winebar { 
    public int Add(int i, int j) { 
     return i + j; 
    } 
    public void FooBar() {} 
} 

public class Adder2 : ICanAdd { 
    public int Add(int i, int j) { 
     return (i + 12) + (j - 12); //yeeeeeaaaah 
    } 
} 

[InterfaceSpecification] 
public class WithOtherPlugins : AppliesToAll<ICanAdd> 
{ 
    [TestCase(1, 2, 3)] 
    [TestCase(-1, 2, 1)] 
    [TestCase(0, 0, 0)] 
    public void CanAddOrSomething(int x, int y, int r) 
    { 
     Assert.AreEqual(subject.Add(x, y), r); 
    } 

    [TestCase(1, 2, Result = 3)] 
    [TestCase(-1, 2, Result = 1)] 
    [TestCase(0, 0, Result = 0)] 
    public int CannAddOrSomethingWithReturn(int x, int y) { 
     return subject.Add(x, y); 
    } 
} 
Cuestiones relacionadas