Angenommen, ich habe ein Programm, das wie folgt aussieht:Mit JMockit und Spring AOP zusammen
@Component
public class MainAction {
public void doTheAction() {
System.out.println("Now doing the action");
}
}
@Aspect
@Component
public class BeforeAspect {
@Autowired
private Logger logger;
@Before("execution(* thepackagename.MainAction.*(..))")
public void doBefore() {
logger.log("The @Before advice has run");
}
}
@Component
public class Logger {
public void log(String s) {
System.out.println(s);
}
}
Dies funktioniert gut, wenn ich es durch Eclipse-laufen (die wichtigste Methode esentially ruft mainAction.doTheAction()
nach mainAction
wird von Frühling erstellt) .
Jetzt möchte ich einen Test schreiben, der sicherstellt, dass die log
Methode korrekt aufgerufen wird, wenn doTheAction
aufgerufen wird. Wir verwenden JMockit für unsere Tests. (Dies ist ein sehr vereinfachter Fall eines Problems, mit dem ich tatsächlich konfrontiert bin; ein komplexerer Logger wird über einen AOP-Aspekt aufgerufen, und der falsche Wert von etwas wird protokolliert. Bevor ich an einem Fix arbeite, versuche ich einen zu schreiben Test, um sicherzustellen, der angemeldete Wert korrekt ist)
Dies ist, was mein (vereinfacht) Test zur Zeit wie folgt aussieht:.
@RunWith(JMockit.class)
@ContextConfiguration(locations = {"classpath:Beans.xml"})
public class MainActionTest {
@Tested
private MainAction mainAction;
@Test
public void testThatLoggerIsCalled(@Injectable Logger logger) {
new Expectations() { {
logger.log(anyString);
} };
mainAction.doTheAction();
}
}
die @ContextConfiguration
nutzlos sein kann. Früher hatte ich versucht @RunWith(SpringJunit4ClassRunner.class)
, weshalb @ContextConfiguration
ist da, aber keiner der spöttischen Sachen wurde behandelt. Außerdem verwende ich @Tested
und @Injectable
anstelle von @Autowired
und @Mocked
, nach dem Vorschlag in this question; ohne diese blieb mainAction
null. Jetzt läuft der Test und Now doing the action
erscheint in der Ausgabe. Aber 10 erscheint nicht (und erscheint nicht einmal, wenn ich nicht die Logger
) verspotten, und die Erwartung schlägt fehl.
Wie kann ich JMockit und AOP zusammen verwenden?
Bearbeiten: Wie gewünscht, habe ich etwas hinzugefügt, um die Classpath-Eigenschaft zu drucken. Hier ist es (mit unwichtigen Teilen einiger Pfadnamen entfernt):
Eclipse workspaces\springtest8\target\test-classes
Eclipse workspaces\springtest8\target\classes
C:\eclipse\plugins\org.junit_4.11.0.v201303080030\junit.jar
C:\eclipse\plugins\org.hamcrest.core_1.3.0.v201303031735.jar
.m2\repository\org\jmockit\jmockit\1.18\jmockit-1.18.jar
.m2\repository\junit\junit\4.11\junit-4.11.jar
.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar
.m2\repository\org\springframework\spring-context\4.2.0.RELEASE\spring-context-4.2.0.RELEASE.jar
.m2\repository\org\springframework\spring-aop\4.2.0.RELEASE\spring-aop-4.2.0.RELEASE.jar
.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar
.m2\repository\org\springframework\spring-beans\4.2.0.RELEASE\spring-beans-4.2.0.RELEASE.jar
.m2\repository\org\springframework\spring-core\4.2.0.RELEASE\spring-core-4.2.0.RELEASE.jar
.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar
.m2\repository\org\springframework\spring-expression\4.2.0.RELEASE\spring-expression-4.2.0.RELEASE.jar
.m2\repository\org\aspectj\aspectjrt\1.8.6\aspectjrt-1.8.6.jar
.m2\repository\org\aspectj\aspectjweaver\1.8.6\aspectjweaver-1.8.6.jar
.m2\repository\org\springframework\spring-test\4.2.0.RELEASE\spring-test-4.2.0.RELEASE.jar
.m2\repository\javax\inject\javax.inject\1\javax.inject-1.jar
/C:/eclipse/configuration/org.eclipse.osgi/bundles/201/1/.cp/
/C:/eclipse/configuration/org.eclipse.osgi/bundles/200/1/.cp/
Edit 2: ich Dinge wurden durch die Arbeit JUnit4 Entfernen von der Registerkarte Bibliotheken in Configure-Erstellungspfad.
Ich bekomme immer noch 'Method testThatLoggerIsCalled sollte keine Parameter haben'. Ich benutze Spring 4.1.0 - versuchte 4.2.0 auch. Außerdem habe Eclipse meine JUnit als 3.8.1 eingerichtet - brauche ich eine spätere Version? Verwenden Sie @Inject von 'javax.inject' oder woanders? – ajb
Dieser Fehler über "habe keine Parameter" tritt auch bei mir auf, aber * nur *, wenn ich Spring 2.5 verwende, das auf dem alten JUnit 4.4 Test Runner basiert. Die minimale JUnit-Version für JMockit * und * Spring Test 4.1 ist JUnit 4.5; Es kann nicht mit 3.8.1 arbeiten (aber das ist wahrscheinlich etwas anderes - Ihre junit.jar im Runtime-Klassenpfad ist höchstwahrscheinlich JUnit 4.x). –
Ich akzeptiere die Antwort, damit das Kopfgeld nicht abläuft. Aber ich werde weiterhin versuchen, die Versionen richtig zu machen, und ich werde Sie auf dem Laufenden halten. – ajb