2011-12-15 47 views
5

Estoy escribiendo una clase de prueba para probar mi clase 'ImporterService'. Este servicio lee un InputStream y crea un objeto a partir de sus datos. El objeto, en este caso una clase de generador, se crea una instancia dentro de la clase 'ImporterService'. Para probar mi clase 'ImporterService', necesito verificar las invocaciones en la clase Builder. Para esto, quiero utilizar un marco de burla, sin embargo, ¿cómo es posible crear una instancia simulada del objeto 'Constructor' fuera de 'ImporterService'?Mocking objeto instanciado interno

El método de mi clase 'ImporterService' se parece a:

 


    public Builder importFrom(BufferedReader reader) throws IOException { 
     String someValue = readFrom(reader); 
     Builder builder = new Builder(); // I need to mock this Builder object... 
     builder.someMethod(someValue);  // to see of a method is called with the expected value 
    } 
 

Estaba pensando en mover la creación de la clase Constructor en un método protegido que puedo anular de la configuración de la prueba. Pero esta solución no me parece muy agradable ya que la clase 'ImporterService' está filtrando cierta lógica interna y permite anular el método por otras clases que no quiero.

Respuesta

2

Si utiliza una biblioteca de inyección de dependencias (como Spring), puede inyectar el objeto simulado en lugar del constructor en la clase ImporterService. O puede reemplazar la llamada al constructor con una llamada a fábrica y usar fábrica, que devuelve simulacros en el código de prueba.

+0

Si está utilizando un buen marco de burla que no es necesario resorte en u otro armazón DI que su unidad prueba. A menos que esté probando su cableado –

0

Suponiendo que está usando jMockt (Se lo recomiendo este marco de burla), usted será capaz de hacer lo siguiente:

@Test 
    public void testFoo(@Mocked Builder builder) { 
     new Expectations() { 
      { 
       new Builder(); 
       returns(builder); 

       builder.setSomemethod() 
       ... 
      } 
     }; 

     assertSame(builder,impoertesService.importFrom(...)); 
    } 
0

Algunos marcos burlones como PowerMock pueden burlarse de construcción de objetos.

0

puede cambiar firma de la función a algo como esto:

public Builder importFrom(BufferedReader reader, Builder builder) throws IOException { 

al hacer esto puede pasar cualquier aplicación ficticia de su caso de prueba. Esta es una forma de inyección de dependencia.

La idea de la inyección de dependencia es solicitar todas sus dependencias y si una clase/función lo hace, el código se vuelve altamente comprobable.

1

sí, se puede hacer ya sea como usted sugiere o:

crear una clase de fábrica en la que se crea Builder objetos y la asigna a la clase de lector. En las pruebas de su unidad, simule esta fábrica y oblíguela a crear un Builder de su elección para que pueda verificar las llamadas de método en su prueba unitaria.

Aquí hay un ejemplo usando EasyMock que muestra cómo se puede lograr esto:

public class Reader{ 
    private BuilderFactory factory = new BuilderFactory(); // Use production factory by default 
    public Builder importFrom(BufferedReader reader) throws IOException { 
     String someValue = readFrom(reader); 
     Builder builder = factory.buildBuilder(); 
     builder.someMethod(someValue);  // to see of a method is called with the expected value 
    } 
} 

En las pruebas unitarias de hacer lo siguiente:

Reader classUnderTest = new Reader(); 
BuilderFactory fakeFactory = EasyMock.createNiceMock(BuilderFactory.class); 
Builder builder = EasyMock.createMock(Builder.class); 
EasyMock.expect(fakeFactory.buildBuilder()).andReturn(builder); 
builder.someMethod("value here"); 
EasyMock.expectLastCall().once(); 
EasyMock.replay(fakeFactory, builder); 
classUnderTest.importFrom(bufferReader); 
// Very that all calls were correctly performed on the builder 
EasyMock.verify(builder); 
Cuestiones relacionadas