Usar Mockito para simular clases con parámetros genéricos


¿Existe un método limpio para burlarse de una clase con parámetros genéricos? Digamos que tengo que burlarme de una clase Foo<T> que necesito pasar a un método que espera un Foo<Bar>. Puedo hacer lo siguiente con bastante facilidad:

Foo mockFoo = mock(Foo.class);
when(mockFoo.getValue).thenReturn(new Bar());

Asumiendo getValue() devuelve el tipo genérico T. Pero eso va a tener gatitos cuando más tarde lo pase a un método esperando Foo<Bar>. ¿Es el casting el único medio de hacer esto?

Author: Tim Clemons, 2009-10-31

5 answers

Creo que necesitas lanzarlo, pero no debería ser tan malo:

Foo<Bar> mockFoo = (Foo<Bar>) mock(Foo.class);
when(mockFoo.getValue).thenReturn(new Bar());
 203
Author: John Paulett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-30 23:12:38

Otra forma de evitar esto es usar @Mock anotación en su lugar. No funciona en todos los casos, pero se ve mucho más sexy:)

Aquí hay un ejemplo:

@RunWith(MockitoJUnitRunner.class)
public class FooTests {

    @Mock
    public Foo<Bar> fooMock;

    @Test
    public void testFoo() {
        when(fooMock.getValue()).thenReturn(new Bar());
    }
}

La MockitoJUnitRunner inicializa los campos anotado con @Mock.

 217
Author: Marek Kirejczyk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-19 11:47:16

Siempre puede crear una clase/interfaz intermedia que satisfaga el tipo genérico que desea especificar. Por ejemplo, si Foo era una interfaz, podría crear la siguiente interfaz en su clase de prueba.

private interface FooBar extends Foo<Bar>
{
}

En situaciones en las que Foo es una clase no final, simplemente podría extender la clase con el siguiente código y hacer lo mismo:

public class FooBar extends Foo<Bar>
{
}

Entonces usted podría consumir cualquiera de los ejemplos anteriores con el siguiente código:

Foo<Bar> mockFoo = mock(FooBar.class);
when(mockFoo.getValue()).thenReturn(new Bar());
 26
Author: dsingleton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-18 13:12:02

Cree un método de utilidad de prueba . Especialmente útil si lo necesitas más de una vez.

@Test
public void testMyTest() {
    // ...
    Foo<Bar> mockFooBar = mockFoo();
    when(mockFooBar.getValue).thenReturn(new Bar());

    Foo<Baz> mockFooBaz = mockFoo();
    when(mockFooBaz.getValue).thenReturn(new Baz());

    Foo<Qux> mockFooQux = mockFoo();
    when(mockFooQux.getValue).thenReturn(new Qux());
    // ...
}

@SuppressWarnings("unchecked") // still needed :( but just once :)
private <T> Foo<T> mockFoo() {
    return mock(Foo.class);
}
 11
Author: acdcjunior,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-16 18:11:33

Aquí hay un caso interesante: el método recibe la colección genérica y devuelve la colección genérica del mismo tipo base. Por ejemplo:

Collection<? extends Assertion> map(Collection<? extends Assertion> assertions);

Este método puede ser burlado con la combinación de Mockito anyCollectionOf matcher y la Respuesta.

when(mockedObject.map(anyCollectionOf(Assertion.class))).thenAnswer(
     new Answer<Collection<Assertion>>() {
         @Override
         public Collection<Assertion> answer(InvocationOnMock invocation) throws Throwable {
             return new ArrayList<Assertion>();
         }
     });
 2
Author: qza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-03 11:59:57