Pregunta

Mi código:

@Component
public class A {
    @Autowired
    private B b;

    public void method() {}
}

public interface X {...}

@Component
public class B implements X {
    ...
}

Quiero poner a prueba en la clase de aislamiento A. ¿Tengo que simulacro de clase B? En caso afirmativo, ¿cómo? Debido a que se autowired y no hay colocador en el que podía enviar el objeto burlado.

¿Fue útil?

Solución

  

Quiero la prueba en clase de aislamiento A.

Se debe absolutamente simulacro B, en lugar de instanciar e inyectar una instancia de B. El punto es que la prueba A B si las obras o no, por lo que debe no permite un B potencialmente roto interfiere con la prueba de A.

Dicho esto, le recomiendo Mockito . Como marcos burlones van, es extremadamente fácil de usar. Se podría escribir algo como lo siguiente:

@Test
public void testA() {
    A a = new A();
    B b = Mockito.mock(B.class); // create a mock of B
    Mockito.when(b.getMeaningOfLife()).thenReturn(42); // define mocked behavior of b
    ReflectionTestUtils.setField(a, "b", b); // inject b into the B attribute of A

    a.method();

    // call whatever asserts you need here
}

Otros consejos

Aquí hay un ejemplo de cómo llegó a mis pruebas de trabajo con Spring 3.1, JUnit 4.7 y 1.9 Mockito:

FooService.java

public class FooService {
    @Autowired private FooDAO fooDAO;
    public Foo find(Long id) {
        return fooDAO.findById(id);
    }
}

FooDAO.java

public class FooDAO {
    public Foo findById(Long id) {
        /* implementation */
    }
}

FooServiceTest.java

@RunWith(MockitoJUnitRunner.class)
public class FooServiceTest {
    @Mock private FooDAO mockFooDAO;
    @InjectMocks private FooService fooService = new FooService();

    @Test public final void findAll() {
        Foo foo = new Foo(1L);
        when(mockFooDAO.findById(foo.getId()).thenReturn(foo);

        Foo found = fooService.findById(foo.getId());
        assertEquals(foo, found);
    }
}

Se puede inyectar el campo a través de la reflexión utilizando ReflectionTestUtils.setField de primavera (o la extensión PrivateAccessor junit) o ??se puede crear un contexto de aplicación simulada y cargar eso. Aunque para una unidad sencilla (no integración) de prueba, estoy a favor de utilizar la reflexión para la simplicidad.

Este foro de debate tiene sentido para mí. Se puede declarar su miembro privado b como un tipo de InterfaceB cual es implementado por la clase B (es decir: orientada al servicio) y luego declarar una clase MockB sería también implementar la misma interfaz. En el contexto de aplicación de entorno de prueba, se declara la clase MockB y su contexto de aplicación de producción se declara la clase B normal y, en cualquier caso, no necesita el código de la clase A que ser cambiado ya que se auto-cableado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top