I'm trying to mock org.springframework.web.client.RestOperations.exchange
in Spock.
Spock fails with
Too few invocations for:
1 * restOperations.exchange("https://test.com", HttpMethod.POST, _ as HttpEntity, String) (0 invocations)
Unmatched invocations (ordered by similarity):
1 * restOperations.exchange('https://test.com', POST, <whatever,[]>, class java.lang.String, [])
I think the problem is related to the fact that the exchange
method is overloaded and the version I'm trying to call has vararg arguments.
How do I define this interaction, so the test succeeds?
MySubject.java:
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.web.client.RestOperations;
public class MySubject {
private final RestOperations rest;
public MySubject(RestOperations rest) {
this.rest = rest;
}
public void doStuff() {
HttpEntity<String> httpEntity = new HttpEntity<>("whatever");
rest.exchange("https://test.com", HttpMethod.POST, httpEntity);
}
}
MyTest.groovy:
import org.apache.http.HttpEntity
import org.springframework.http.HttpMethod
import org.springframework.web.client.RestOperations
import spock.lang.Specification
class MyTest extends Specification {
RestOperations restOperations = Mock(RestOperations)
MySubject subject = new MySubject(restOperations)
def "test"() {
when:
subject.doStuff()
then:
1 * restOperations.exchange("https://test.com", HttpMethod.POST, _ as HttpEntity, String)
}
}
You have multiple problems:
In the application you import org.springframework.http.HttpEntity
, in the test org.apache.http.HttpEntity
. You need to correct that.
The call rest.exchange("https://test.com", HttpMethod.POST, httpEntity);
in your application does not even compile because there is no such signature in the RestOperations
class. You need to add the parameter String.class
.
In the test you need to reflect the method signature including the varargs, i.e. the real method signature has 5 arguments.
If you fix all of these your test runs smoothly:
package de.scrum_master.stackoverflow.q61135628;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.web.client.RestOperations;
public class MySubject {
private final RestOperations rest;
public MySubject(RestOperations rest) {
this.rest = rest;
}
public void doStuff() {
HttpEntity<String> httpEntity = new HttpEntity<>("whatever");
rest.exchange("https://test.com", HttpMethod.POST, httpEntity, String.class);
}
}
package de.scrum_master.stackoverflow.q61135628
import org.springframework.http.HttpMethod
import org.springframework.web.client.RestOperations
import spock.lang.Specification
class MyTest extends Specification {
RestOperations restOperations = Mock()
MySubject subject = new MySubject(restOperations)
def "test"() {
when:
subject.doStuff()
then:
1 * restOperations.exchange("https://test.com", HttpMethod.POST, _, String, _)
// Or if you want to be more specific:
// 1 * restOperations.exchange("https://test.com", HttpMethod.POST, _, String, [])
}
}