No further requests expected while MockRestServiceServer was set to ExpectedCount.manyTimes()

13,766

This issue can be resolved using @DirtiesContext on the test class, alongside with the @RunWith:

 * Test annotation which indicates that the
 * {@link org.springframework.context.ApplicationContext ApplicationContext}
 * associated with a test is <em>dirty</em> and should therefore be closed
 * and removed from the context cache.
 *
 * <p>Use this annotation if a test has modified the context &mdash; 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.
 *
 * <p>{@code @DirtiesContext} may be used as a class-level and method-level
 * annotation within the same class or class hierarchy. In such scenarios, the
 * {@code ApplicationContext} will be marked as <em>dirty</em> before or
 * after any such annotated method as well as before or after the current test
 * class, depending on the configured {@link #methodMode} and {@link #classMode}.
 *

And here are Docs on the matter: https://docs.spring.io/spring/docs/5.0.6.RELEASE/spring-framework-reference/testing.html#dirtiescontext

Share:
13,766
Oleg K.
Author by

Oleg K.

Updated on June 12, 2022

Comments

  • Oleg K.
    Oleg K. almost 2 years

    I have following test class for my spring-integration application that passes sucessfully being launched alone

    @SpringBootTest(classes = {BackupTestDefinition.class})
    @ActiveProfiles({"test", "dev"})
    @RunWith(SpringRunner.class)
    public class BackupServiceTest {
        @Value(value = "${ne.endpoint}")
        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.

  • Oleg K.
    Oleg K. about 6 years
    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.
  • Artem Bilan
    Artem Bilan about 6 years
    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.