2015-10-22 6 views
5

ich bin mit einem sehr seltsamen Problem konfrontiert.Ambiguous Mockito - 0 Matchers erwartet, 1 aufgezeichnet (InvalidUseOfMatchersException)

URL = "/my/specific/url/"; 
when(this.restHelperMock.post(
eq(myEnum), 
eq(this.config.apiEndpoint() + URL), 
any(JSONObject.class))).thenReturn(new JSONObject(myDesiredJsonContent)); 

oder sogar mit enthält

URL = "/my/specific/url/"; 
when(this.restHelperMock.post(
eq(myEnum), 
contains(this.config.apiEndpoint() + URL), 
any(JSONObject.class))).thenReturn(new JSONObject(myDesiredJsonContent)); 

mich selbst

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers! 
0 matchers expected, 1 recorded: 

This exception may occur if matchers are combined with raw values: 
    //incorrect: 
    someMethod(anyObject(), "raw String"); 
When using matchers, all arguments have to be provided by matchers. 
For example: 
    //correct: 
    someMethod(anyObject(), eq("String by matcher")); 

For more info see javadoc for Matchers class. 

gibt, wenn ich RAW Ausdrücke nicht verwenden.
Merkwürdig, wenn ich das enthält Verfahren zu ändern:

URL = "/my/specific/url/"; 
when(this.restHelperMock.post(
eq(myEnum), 
contains(URL), 
any(JSONObject.class))).thenReturn(new JSONObject(myDesiredJsonContent)); 

den Endpunkt weggelassen, es funktioniert.

Die Config und RestHelper beide verspottet:

this.restHelperMock = mock(RESTHelper.class); 
this.config = mock(MyBMWConfiguration.class); 

when(this.config.apiEndpoint()).thenReturn("http://host:port/api"); 

Die URL mit ApiEndpoint gleich, was ich verspotten wollte, auch wenn es nicht wäre, ich eine Nullpointer bekommen sollte, wegen falscher Verspottung. Aber hier habe ich keine ideea.

Vielen Dank für Ihre Antworten.

+0

Sind deine 'contains' und' eq' beide von 'Mockito', weil selbst' hamcrest' beides hat. –

+0

Ich vermute, das Problem könnte sein, dass Sie während des 'eq (...)' Aufrufs eine verspottete Methode ('this.config.apiEndpoint()') aufrufen. Versuchen Sie, einfach die vollständige URL dorthin zu setzen (http: // host: port/api/my/specific/url /), anstatt dort einen anderen Mock aufzurufen, was Mockito verwirren könnte, da er sich auf interne Zustände für das Mocking stützt. –

+0

@ FlorianSchaetz danke, das war die Lösung. Ich hätte nicht gedacht, dass das passieren könnte. Kannst du bitte ein Anwsser schreiben, damit ich es annehmen kann? –

Antwort

4

Das Problem scheint zu sein, dass Sie eine gespottete Methode this.config.apiEndpoint() während des Aufrufs eq (...) aufrufen. Versuchen Sie, einfach die vollständige URL dorthin zu setzen (host: port/api/my/specific/url), anstatt dort einen anderen Mock aufzurufen, was Mockito verwirren könnte, da es sich auf interne Zustände für das Mocking stützt.

Um ganz ehrlich zu sein, ich bin nicht so tief in Mockito, dass ich erklären könnte, warum dies geschieht, aber ich werde wahrscheinlich versuchen, in es einen Tag ;-)

bearbeiten zu debuggen: Merkwürdigerweise scheine ich nicht in der Lage sein, es mit einem einfacheren Testfall zu reproduzieren. Es scheint hier mehr zu geben als man sieht.

+1

Hmm, ich kann total sehen, wie das passieren kann. Ab dem Zeitpunkt, zu dem der erste Matcher aufgerufen wird, ab dem Zeitpunkt, an dem er aufgerufen wird, möchten Sie NICHT mit anderen Mocks interagieren. Dies liegt daran, dass, wenn Sie Matcher verwenden, dieser ganze interne Stapel von Matcher-Aufrufen aufgebaut wird. Gut entdeckt, Florian. Um dies zu beheben, könnten Sie den Aufruf von 'this.config.apiEndpoint()' in einer eigenen Zeile vor der Zeile mit 'when' platzieren. –

Verwandte Themen