- Why mockServer.verify is needed in MockRestServiceServer
- Solution
- Saved searches
- Use saved searches to filter your results more quickly
- Make MockRestServiceServer error messages more descriptive [SPR-12230] #16845
- Make MockRestServiceServer error messages more descriptive [SPR-12230] #16845
- Comments
- No further requests expected while MockRestServiceServer was set to ExpectedCount.manyTimes()
- Oleg K.
- Comments
- Saved searches
- Use saved searches to filter your results more quickly
- MockRestServiceServer.verify() did not work with single API testing if project has more than one API #28278
- MockRestServiceServer.verify() did not work with single API testing if project has more than one API #28278
- Comments
- Affects: 5.3.18
- Spring – No further requests expected while MockRestServiceServer was set to ExpectedCount.manyTimes()
- Best Solution
Why mockServer.verify is needed in MockRestServiceServer
At the end of the test use verify() to ensure all expected requests were actually performed.
Solution
The idea of MockRestServiceServer is that it allows you mock the external server such that the RestTemplate does not really need to send the requests to the actual server during the testing. Instead it just sends the requests to this MockRestServiceServer (think that it is a kind of in-memory server) and it will return the configured mocked responses for the corresponding requests.
You have to configure all the expected requests that the MockRestServiceServer will received and its corresponding responds before the test.
So basically there are two things needed to be verified which are :
- For every request sent by RestTemplate , there should be a mocked response configured for that request in the MockRestServiceServer
- For all the requests that are to be expected to be received on the MockRestServiceServer , the RestTemplate should really send out all of these expected requests.
(1) will be verified automatically whenever the RestTemplate send out a request. The exception no further requests expected: HTTP that you mentioned is because it fails (1) (i.e. forget to stub this request in the MockRestServiceServer )
(2) will not be verified automatically . You have to call MockRestServiceServer.verify() manually in order to verify it.
mockServer.expect(requestTo(new URI("https://www.yahoo.com"))) .andExpect(method(HttpMethod.GET)).andRespond(withSuccess()); mockServer.expect(requestTo(new URI("https://www.google.com"))) .andExpect(method(HttpMethod.GET)).andRespond(withSuccess()); mockServer.expect(requestTo(new URI("https://www.stackoverflow.com"))) .andExpect(method(HttpMethod.GET)).andRespond(withSuccess()); restTemplate.getForEntity("https://www.yahoo.com", String.class); restTemplate.getForEntity("https://www.google.com", String.class);
Without mockServer.verify() , the test still passes although RestTemplate does not send the request to https://www.stackoverflow.com which the MockServer is expected to be received.
But with mockServer.verify() , it can check that and hence fails the test.
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make MockRestServiceServer error messages more descriptive [SPR-12230] #16845
Make MockRestServiceServer error messages more descriptive [SPR-12230] #16845
in: test Issues in the test module status: backported An issue that has been backported to maintenance branches type: enhancement A general enhancement
Comments
Elnur Abdurrakhimov opened SPR-12230 and commented
Currently, when making an unexpected request to the mock server, I get an exception java.lang.AssertionError: No further requests expected .
It’s a real pain to find out which request is at fault, because there is not enough information in that exception’s stacktrace.
It would be really helpful to have all the expected requests, that were already done, to be displayed. It should also display which request was expected next and which one came instead and caused the expectations to fail.
Affects: 3.2 GA
Issue Links:
Backported to: 4.0.8, 3.2.12
The text was updated successfully, but these errors were encountered:
No further requests expected while MockRestServiceServer was set to ExpectedCount.manyTimes()
This issue can be resolved using @DirtiesContext on the test class, alongside with the @RunWith :
* Test annotation which indicates that the * * associated with a test is dirty and should therefore be closed * and removed from the context cache. * * Use this annotation if a test has modified the context — for * example, by modifying the state of a singleton bean, modifying the state * of an embedded database, etc. Subsequent tests that request the same * context will be supplied a new context. * *
may be used as a class-level and method-level * annotation within the same class or class hierarchy. In such scenarios, the * will be marked as dirty before or * after any such annotated method as well as before or after the current test * class, depending on the configured and . *
Oleg K.
Comments
I have following test class for my spring-integration application that passes sucessfully being launched alone
@SpringBootTest(classes = ) @ActiveProfiles() @RunWith(SpringRunner.class) public class BackupServiceTest < @Value(value = "$") private String ne; @Autowired private RestTemplate restTemplate; private MockRestServiceServer mockServer; @Before public void setup() < mockServer = MockRestServiceServer.bindTo(restTemplate).build(new UnorderedRequestExpectationManager()); mockServer.expect(ExpectedCount.manyTimes(), requestTo(UriComponentsBuilder.fromHttpUrl(ne).build().toUri())).andExpect(method(HttpMethod.POST)).andRespond(withSuccess()); >@Test public void testNotificationProcessing() throws IOException, InterruptedException, InitializationException, ExecutionException < //some testing code >>
But I have another test that has other settings (ExpectedCount.times(1)) for the same endpoint and has different TestDefinition. So there are couple of contexts cached in this test suite. And when I launch them together I receive following exception
at org.springframework.test.web.client.AbstractRequestExpectationManager.createUnexpectedRequestError(AbstractRequestExpectationManager.java:141) at org.springframework.test.web.client.UnorderedRequestExpectationManager.validateRequestInternal(UnorderedRequestExpectationManager.java:49) at org.springframework.test.web.client.AbstractRequestExpectationManager.validateRequest(AbstractRequestExpectationManager.java:76) at org.springframework.test.web.client.MockRestServiceServer$MockClientHttpRequestFactory$1.executeInternal(MockRestServiceServer.java:289) at org.springframework.mock.http.client.MockClientHttpRequest.execute(MockClientHttpRequest.java:94) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:659) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:620) at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:538) Caused by: java.lang.AssertionError: No further requests expected: HTTP POST
After hours of debugging I found out that settings were successfully applied, but looks like restTemplate was called from another context where number of attempts was exhausted. Can you please help me to find out how this issue can be resolved.
Is this the only possible solution for this problem? As my test suite contains a lot of test classes and changing them is not desired.
Well, if you don’t cache and don’t share context between tests, you are more stable and you don’t need hours of debugging to figure out what is the problem. That’s just a matter of adding one annotation. On the other hand this is @Inherited , so you can specify it on the super class for those tests. That is the way we went in our projects after some experience with a ton of unexpected failures, especially when we deal with shared resources (DB, JMS, files etc.) and some scheduled tasks.
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MockRestServiceServer.verify() did not work with single API testing if project has more than one API #28278
MockRestServiceServer.verify() did not work with single API testing if project has more than one API #28278
in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket) status: invalid An issue that we don’t feel is valid
Comments
Affects: 5.3.18
MockRestServiceServer.verify() did not work with single API testing if project has more than one API.
@Component public class Test < @Autowired private RestTemplate restTemplate; @Scheduled(fixedDelay = 3000) public void schedule1() < restTemplate.getForEntity(URI.create("http://localhost:9090/api1"), String.class); > @Scheduled(fixedDelay = 3000) public void schedule2() < restTemplate.getForEntity(URI.create("http://localhost:9090/api2"), String.class); > >
@ExtendWith(< SpringExtension.class >) @SpringBootTest(classes = Demo1Application.class) class TestTest < @Autowired private RestTemplate restTemplate; private MockRestServiceServer mockServer; @Test void testSchedule1() < mockServer = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build(); mockServer .expect(ExpectedCount.manyTimes(), MockRestRequestMatchers.requestTo(new StringStartsWith("http://localhost:9090/api1"))) .andExpect(MockRestRequestMatchers.method(HttpMethod.GET)) .andRespond(MockRestResponseCreators.withStatus(HttpStatus.OK).body("")); mockServer.verify(Duration.ofSeconds(10)); > @Test void testSchedule2() < mockServer = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build(); mockServer .expect(ExpectedCount.manyTimes(), MockRestRequestMatchers.requestTo(new StringStartsWith("http://localhost:9090/api2"))) .andExpect(MockRestRequestMatchers.method(HttpMethod.GET)) .andRespond(MockRestResponseCreators.withStatus(HttpStatus.OK).body("")); mockServer.verify(Duration.ofSeconds(10)); > >
If the schedule1 executes first, then the testSchedule2 fails and vice versa.
java.lang.AssertionError: No further requests expected: HTTP GET http://localhost:9090/api1 0 request(s) executed.
The Map requestFailures in AbstractRequestExpectationManager seems stores all executed APIs even it is not expected.
The text was updated successfully, but these errors were encountered:
Spring – No further requests expected while MockRestServiceServer was set to ExpectedCount.manyTimes()
But I have another test that has other settings (ExpectedCount.times(1)) for the same endpoint and has different TestDefinition. So there are couple of contexts cached in this test suite. And when I launch them together I receive following exception
at org.springframework.test.web.client.AbstractRequestExpectationManager.createUnexpectedRequestError(AbstractRequestExpectationManager.java:141) at org.springframework.test.web.client.UnorderedRequestExpectationManager.validateRequestInternal(UnorderedRequestExpectationManager.java:49) at org.springframework.test.web.client.AbstractRequestExpectationManager.validateRequest(AbstractRequestExpectationManager.java:76) at org.springframework.test.web.client.MockRestServiceServer$MockClientHttpRequestFactory$1.executeInternal(MockRestServiceServer.java:289) at org.springframework.mock.http.client.MockClientHttpRequest.execute(MockClientHttpRequest.java:94) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:659) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:620) at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:538) Caused by: java.lang.AssertionError: No further requests expected: HTTP POST
After hours of debugging I found out that settings were successfully applied, but looks like restTemplate was called from another context where number of attempts was exhausted. Can you please help me to find out how this issue can be resolved.
Best Solution
This issue can be resolved using @DirtiesContext on the test class, alongside with the @RunWith :
* Test annotation which indicates that the * * associated with a test is dirty and should therefore be closed * and removed from the context cache. * * Use this annotation if a test has modified the context — for * example, by modifying the state of a singleton bean, modifying the state * of an embedded database, etc. Subsequent tests that request the same * context will be supplied a new context. * *
may be used as a class-level and method-level * annotation within the same class or class hierarchy. In such scenarios, the * will be marked as dirty before or * after any such annotated method as well as before or after the current test * class, depending on the configured and . *