2010-02-19 6 views
15

So habe ich schon seit einer Weile die Klassenerweiterung von EasyMock verwendet. Ganz plötzlich erhalte ich diese Ausnahme, aber nur, wenn ich die gesamte Testsuite laufen:Während der Suite Tests EasyMock sagt 0 Matcher erwartet 1 aufgezeichnet

java.lang.IllegalStateException: 0 matchers expected, 1 recorded. 
at org.easymock.internal.ExpectedInvocation.createMissingMatchers(ExpectedInvocation.java:42) 
at org.easymock.internal.ExpectedInvocation.<init>(ExpectedInvocation.java:34) 
at org.easymock.internal.ExpectedInvocation.<init>(ExpectedInvocation.java:26) 
at org.easymock.internal.RecordState.invoke(RecordState.java:64) 
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:24) 
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:56) 
at org.easymock.classextension.internal.ClassProxyFactory$1.intercept(ClassProxyFactory.java:74) 
at com.protrade.soccersim.data.emulator.matrix.PositionCategoryMatrix$$EnhancerByCGLIB$$c5298a7.getPossession(<generated>) 
at com.protrade.soccersim.data.emulator.stats.team.PossessionCalculatorUnitTest.testDeterminePossessionHomeWin(PossessionCalculatorUnitTest.java:45) 

Die beteiligten Code ist diese kleine Schönheit (getrimmt ein bisschen):

@Before 
public void setUp() throws Exception { 
    homeTeam = createMock(PositionCategoryMatrix.class); 
    awayTeam = createMock(PositionCategoryMatrix.class); 
    ... 
} 

@Test 
public void testDeterminePossessionHomeWin() { 
    expect(homeTeam.getPossession()).andReturn(0.15151515); 
    expect(awayTeam.getPossession()).andReturn(0.01515152); 
    replay(homeTeam, awayTeam); 
    ... 
} 

Die Ausnahme wird auf den ersten erwartet. Und es macht wirklich keinen Sinn. Es sagt, es wird ein Matcher, aber die Methode braucht nicht einmal ein Argument. Und seltsam genug ist es nur während Testsuiten! Ich erstelle einen neuen Mock im @Before, also sollte er nichts von woanders erben (nicht dass eine andere Methode einen Matcher hätte)

Also, irgendwelche Ideen?

+0

Ich bekomme das auch (der Hauptunterschied zwischen diesem und jedem anderen ähnlichen Google-Ergebnis auf die Fehlermeldung ist, dass die aufgezeichnete Nummer größer ist als die erwartete Zahl ... das bedeutet, es ist kein "Missing Matcher" verursacht durch einen konstanten/matcher mix.) Hier geht es um den trivialsten Einsatz von EasyMock möglich - wie habe ich das vorher noch nie erlebt? (Ich habe es in 2.5.2 und 3.0 mit ähnlichen Ergebnissen versucht.) – Jared

Antwort

1

Ich laufe auf ein ähnliches Problem. Nach dem, was ich beobachtet habe, werden sogar Methodenrückgaben mithilfe von Matchers abgeglichen. Wenn also Ihre erste Methode aus irgendeinem Grund fehlschlägt, befindet sich der Matcher für die Rückkehr-Übereinstimmung immer noch im Stapel. Das könnte ein Grund sein, warum 1 Matcher aufgezeichnet werden, auch wenn Ihre Methode kein Argument benötigt. Grundsätzlich hat der erste Methodenaufruf niemals einen Wert zurückgegeben.

1

Welche Version von Easymock verwenden Sie?
las ich ein post über die Veröffentlichung von v.2.5.2 und previuous Versionen einen

stummen Fehler auf der Capture-

Versuch zu verwenden EasyMock 2.5.2+

4

haben könnte Es stimmt zwar, dass dies eine unechte Nachricht sein kann, die von einem "albernen" EasyMock-Bug herrührt, aber es ist auch sehr wahrscheinlich, dass die EasyMock-API nicht verwendet wird. In meinem Fall kam die Nachricht von diesem JUnit 3.8 Test (und wie Sie, das passiert nur, wenn ich meine ganze Reihe von Tests lief und nur über Maven, Eclipse-Details):

public void testSomething() { 
    // Set up 
    MyArgumentType mockArg = (MyArgumentType) EasyMock.anyObject(); // bad API usage 

    // Invoke the method under test 
    final String result = objectUnderTest.doSomething(mockArg); 

    // Verify (assertions, etc.) 
    ... 
} 

Statt ANYOBJECT der Verwendung von() Ich hätte createMock (MyArgumentType.class) oder eine seiner Varianten verwenden sollen. Ich weiß nicht, was ich dachte, ich habe Millionen dieser Tests geschrieben und die API richtig benutzt.

Das verwirrende Bit ist, dass der Test, der mit der Meldung "falsche Anzahl von Matchern" fehlschlägt, nicht unbedingt (oder überhaupt?) Derjenige ist, in dem Sie die API falsch verwendet haben. Es könnte der erste Test sein, der nach dem fehlerhaften Test ausgeführt wurde, der eine replay() - oder verify() -Methode enthält, aber ich habe dies nicht experimentell verifiziert.

+0

Genau das ist uns passiert. Jemand verwendete einen Matcher außerhalb einer 'EasyMock.expect (...)' Methode und vergiftete den EasyMock Zustand – MusikPolice

+0

Interessant. Wohlgemerkt, ich denke, die Java-Welt im Allgemeinen ist nach Mockito (Zitat erforderlich) gegangen, da sie viel typsicherer ist. –

+0

Mir wurde das schon gesagt, aber wir haben zu diesem Zeitpunkt weit über 1.5k Tests in EasyMock geschrieben, also ist es unwahrscheinlich, dass wir bald umsteigen werden – MusikPolice

2

Ich hatte die gleiche Fehlermeldung. Ich verwendete (versehentlich) eine isA() - Deklaration in dem Anruf für die getestete Klasse

Ie.

classUnderTest.callStateChanged(calls, isA(LoggingOnlyListener.class)); 

wenn ich meine:

classUnderTest.callStateChanged(calls, new LoggingOnlyListener()); 

Und es war der Test nach diesem, die jedes Mal gescheitert.

2

Ich bin gerade in dieses Problem geraten, und ich denke, dass ich es geschafft habe, es herauszufinden.Für mich war es wegen des vorherigen Tests (der in einer anderen Klasse ist), wo ich einen EasyMock-Matcher in einer Assert.assertEquals-Methode (falsch) verwendet habe.

Es scheint, EasyMock konnte sich nicht über den zusätzlichen Matcher beschweren, der gemeldet wurde, bis die erste erwartet Methoden aufgerufen wurde.

9

Ich war es leid, dies mit jeder neuen Legacy-Code-Basis mit EasyMock zu sehen, mit der ich arbeiten musste. Schreibe einen neuen EasyMock-Test nach dem Buch und alle plötzlichen Zufallstests beginnen zu scheitern, weil Matchers nie erfasst wurden. Also schaute ich mir an, wie EasyMock diese Matchers speichert. Es verwendet eine letzte Klasse LastControl, in dieser Klasse sind ein paar Threadlocals, wo verschiedene Dinge gespeichert werden. Einer davon war für die Matchers. Glücklicherweise gibt es dort eine statische Methode, um alle Matchers aus dem Threadlocal zu ziehen, die noch dort sind. So gab das mir diese Idee (mit Hilfe eines Kollegen, dank Sven, er Kredit wollte)

/** 
* Base class to make sure all EasyMock matchers are cleaned up. This is not pretty but it will work 
* 
* @author N069261KDS 
* 
*/ 
public class BaseTest { 

    @Before 
    public void before(){ 
    LastControl.pullMatchers(); 
    } 

    @After 
    public void after(){ 
    LastControl.pullMatchers(); 
    } 

} 

Basicly lassen Sie Ihren Test, der mit dem Matchers Fehler fehlschlagen von dieser Klasse erweitern und Sie sind sicher, die Matchers sind gereinigt. Beachten Sie, das ist ein Problem. Die beanstandeten Tests hätten von Anfang an richtig geschrieben werden müssen. Aber wenn du dich durch mehr als 5000 Tests waten musst, ist dies das kleinere Übel. Ich hoffe, dies wird den Menschen helfen!

+0

Das funktioniert wie ein Zauber !!! –

Verwandte Themen