Tengo una clase de la siguiente manera:
public class A {
public A(String test) {
bla bla bla
}
public String check() {
bla bla bla
}
}
La lógica en el constructor A(String test)
y check()
son las cosas de las que estoy tratando de burlarme. Quiero cualquier llamada como: new A($$$any string$$$).check()
devuelve una cadena ficticia "test"
.
Lo intenté:
A a = mock(A.class);
when(a.check()).thenReturn("test");
String test = a.check(); // to this point, everything works. test shows as "tests"
whenNew(A.class).withArguments(Matchers.anyString()).thenReturn(rk);
// also tried:
//whenNew(A.class).withParameterTypes(String.class).withArguments(Matchers.anyString()).thenReturn(rk);
new A("random string").check(); // this doesn't work
Pero no parece estar funcionando. new A($$$any string$$$).check()
sigue pasando por la lógica del constructor en lugar de buscar el objeto simulado de A
.
Respuestas:
El código que publicaste funciona para mí con la última versión de Mockito y Powermockito. ¿Quizás no has preparado A? Prueba esto:
A.java
public class A { private final String test; public A(String test) { this.test = test; } public String check() { return "checked " + this.test; } }
MockA.java
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @PrepareForTest(A.class) public class MockA { @Test public void test_not_mocked() throws Throwable { assertThat(new A("random string").check(), equalTo("checked random string")); } @Test public void test_mocked() throws Throwable { A a = mock(A.class); when(a.check()).thenReturn("test"); PowerMockito.whenNew(A.class).withArguments(Mockito.anyString()).thenReturn(a); assertThat(new A("random string").check(), equalTo("test")); } }
Ambas pruebas deben pasar con mockito 1.9.0, powermockito 1.4.12 y junit 4.8.2
fuente
PrepareForTest
Que yo sepa, no puedes burlarte de los constructores con mockito, solo métodos. Pero de acuerdo con la wiki en la página de códigos de Google de Mockito, hay una manera de burlarse del comportamiento del constructor creando un método en su clase que devuelva una nueva instancia de esa clase. entonces puedes burlarte de ese método. A continuación se muestra un extracto directamente de la wiki de Mockito :
Si solo desea devolver un objeto simulado de su clase, creo que esto debería funcionar para usted. En cualquier caso, puede leer más sobre la creación de objetos simulados aquí:
http://code.google.com/p/mockito/wiki/MockingObjectCreation
fuente
Sin usar Powermock ... Vea el ejemplo a continuación basado en la respuesta de Ben Glasser, ya que me tomó algo de tiempo resolverlo ... espero que ahorre algunas veces ...
Clase original:
public class AClazz { public void updateObject(CClazz cClazzObj) { log.debug("Bundler set."); cClazzObj.setBundler(new BClazz(cClazzObj, 10)); } }
Clase modificada:
@Slf4j public class AClazz { public void updateObject(CClazz cClazzObj) { log.debug("Bundler set."); cClazzObj.setBundler(getBObject(cClazzObj, 10)); } protected BClazz getBObject(CClazz cClazzObj, int i) { return new BClazz(cClazzObj, 10); } }
Clase de prueba
public class AClazzTest { @InjectMocks @Spy private AClazz aClazzObj; @Mock private CClazz cClazzObj; @Mock private BClazz bClassObj; @Before public void setUp() throws Exception { Mockito.doReturn(bClassObj) .when(aClazzObj) .getBObject(Mockito.eq(cClazzObj), Mockito.anyInt()); } @Test public void testConfigStrategy() { aClazzObj.updateObject(cClazzObj); Mockito.verify(cClazzObj, Mockito.times(1)).setBundler(bClassObj); } }
fuente
Con mockito puede usar withSettings (), por ejemplo, si CounterService requiere 2 dependencias, puede pasarlas como una simulación:
UserService userService = Mockito.mock(UserService.class); SearchService searchService = Mockito.mock(SearchService.class); CounterService counterService = Mockito.mock(CounterService.class, withSettings().useConstructor(userService, searchService));
fuente
Mockito tiene limitaciones para probar métodos finales, estáticos y privados.
con la biblioteca de pruebas jMockit, puede hacer algunas cosas de manera muy fácil y directa como se muestra a continuación:
Constructor simulado de una clase java.io.File:
new MockUp<File>(){ @Mock public void $init(String pathname){ System.out.println(pathname); // or do whatever you want } };
Simulacros de un método estático:
fuente