J'ai une classe DummyResource et un fichier DummyTarget, ainsi qu'une classe de test TestDummyResource comme ci-dessous, mais l'objet fictif DummyResource dr = mock(DummyResource.class)
ne fonctionne que lorsque j'appelle le constructeur dans une classe normale. en utilisant l'objet simulé.
Versions:
powermock 1.4.12 mockito 1.9.0 junit 4.8.2
DummyTarget.Java:
import Java.io.IOException;
import Java.io.OutputStream;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.StreamingOutput;
public class DummyTarget {
public StreamingOutput testMocking() {
return new StreamingOutput() {
@Override
public void write(OutputStream arg0) throws IOException, WebApplicationException {
new DummyResource();
}
};
}
}
DummyResource.Java:
package com.smin.dummy;
public class DummyResource {
public DummyResource() {
System.out.println("mock failure");
}
}
TestDummyResource.Java:
package com.smin.dummy;
import static org.mockito.Mockito.mock;
import Java.io.IOException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.StreamingOutput;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({DummyResource.class,DummyTarget.class})
public class TestDummyResource {
@Before
public void setUp() throws Exception {
DummyResource dr = mock(DummyResource.class);
PowerMockito.whenNew(DummyResource.class).withNoArguments().thenReturn(dr);
}
@Test
public void testMocked() throws WebApplicationException, IOException {
new DummyResource(); // it uses the mocked object dr here,
//doesn't print "mock failure"
StreamingOutput sop = new DummyTarget().testMocking();
sop.write(null); // it calls DummyResource's constructor,
// prints ""mock failure"" here
}
}
Il semble qu'une classe anonyme puisse hériter du package de la classe qui la définit. Pouvez-vous essayer la forme générique de PrepareForTest
?:
@PrepareForTest("com.smin.dummy.*")
Si cela ne fonctionne pas, vous pouvez essayer le fusil de chasse PrepareEverythingForTest
Annotation.
Vous devez avoir préparé la classe appelant le constructeur, et non la classe sur laquelle le constructeur est appelé, les éléments suivants devraient vous aider:
@PrepareForTest(DummyTarget.class)
Pour plus d'informations, consultez this page.
En fait, vous devez préparer pour tester la classe qui appelle le constructeur, et non la classe sur laquelle le constructeur a été appelé. Voir https://github.com/jayway/powermock/wiki/MockConstructor .
Dans votre cas, vous devez utiliser @PrepareForTest (DummyTarget.class).
J'ai eu le même problème et je l'ai résolu en utilisant whenNew avec un nom complet. Le nom qualifié complet d'une classe anonyme interne dans votre cas est:
DummyTarget.class + "$1"
vous devriez donc créer une maquette de cette classe:
DummyResource dr = mock(Class.forName(DummyTarget.class + "$1"));
et cela fonctionnera pour vous.
De plus, n'oubliez pas de préparer le cours DummyTarget:
@PrepareForTest(DummyTarget.class)
J'espère que ça a aidé =]