cómo probar adecuadamente una clase abstracta

Actualmente estoy en el proceso de crear una prueba unitaria para una clase abstracta, llamada Component . VS2008 compiló mi progtwig sin problemas, así que pude crear un proyecto de prueba de unidad dentro de la solución. Sin embargo, una cosa que he notado es que cuando se creó el archivo de prueba, existen estos métodos que nunca había visto antes:

 internal virtual Component CreateComponent() { // TODO: Instantiate an appropriate concrete class. Component target = null; return target; } internal virtual Component_Accessor CreateComponent_Accessor() { // TODO: Instantiate an appropriate concrete class. Component_Accessor target = null; return target; } 

Supongo que estos son para crear una clase de Component concreta.

Dentro de cada método de prueba, hay esta línea:

Component target = CreateComponent(); // TODO: Initialize to an appropriate value

¿Cómo puedo inicializar esto a un valor apropiado? O, ¿cómo puedo crear una instancia de una clase concreta apropiada, como se indica anteriormente en los métodos CreateComponent y CreateComponent_Accessor ?

Aquí está el constructor de la clase abstracta, para información adicional:

protected Component(eVtCompId inComponentId, eLayer inLayerId, IF_SystemMessageHandler inMessageHandler)

No puedes instanciar una clase abstracta. Por lo tanto, podría escribir una implementación simulada de esta clase abstracta (donde debería implementar los miembros abstractos) en su proyecto de prueba de unidad y luego llamar a los métodos que está tratando de probar. Podría tener diferentes implementaciones simuladas para probar varios métodos de su clase.

Como alternativa a escribir una implementación simulada, puede utilizar un marco simulado como Rhino Mocks, Moq, NSubstitute, … que podría simplificar esta tarea y permitirle definir expectativas para los miembros abstractos de la clase.


ACTUALIZAR:

Como se solicita en la sección de comentarios, aquí hay un ejemplo.

Supongamos que tiene la siguiente clase abstracta que desea probar por unidad:

 public abstract class FooBar { public abstract string Foo { get; } public string GetTheFoo() { return "Here's the foo " + Foo; } } 

Ahora, en su proyecto de prueba de unidad, puede implementarlo escribiendo una clase derivada que implemente los miembros abstractos con valores simulados:

 public class FooBarMock : FooBar { public override string Foo { get { return "bar" } } } 

y luego podrías escribir tu prueba de unidad contra el método GetTheFoo :

 // arrange var sut = new FooBarMock(); // act var actual = sut.GetTheFoo(); // assert Assert.AreEqual("Here's the foo bar", actual); 

y con un marco simulado (Moq en mi ejemplo) no necesita implementar esta clase abstracta en la prueba unitaria, pero podría usar directamente el marco simulado para definir las expectativas de los miembros abstractos en los que se basa el método bajo prueba:

 // arrange var sut = new Mock(); sut.Setup(x => x.Foo).Returns("bar"); // act var actual = sut.Object.GetTheFoo(); // assert Assert.AreEqual("Here's the foo bar", actual);