简体   繁体   中英

How to get wiremock running before the spring boot application status up?

I have an integration test for a spring boot micro-service. The problem is that the service calls an external service (via REST) on startup. I'm using WireMock to mock the call. Spring makes the application start before WireMock is started. Because of this, the rest call fails and so does the service.

The call is made by a library that is also made by our company, so I cannot change anything there.

Do you have any suggestions for me?

you might create static instance of WireMockServer in your test. Here is a code sample:

@RunWith(SpringRunner.class)
@SpringBootTest
public class YourApplicationTests {
    static WireMockServer mockHttpServer = new WireMockServer(10000); // endpoint port here

    @BeforeClass
    public static void setup() throws Exception {
        mockHttpServer.stubFor(get(urlPathMatching("/")).willReturn(aResponse().withBody("test").withStatus(200)));
        mockHttpServer.start();
    }

    @AfterClass
    public static void teardown() throws Exception {
        mockHttpServer.stop();
    }

    @Test
    public void someTest() throws Exception {
        // your test code here
    }
}

The Spring Boot team have built a WireMock integration. Might be worth checking it out rather than rolling your own: http://cloud.spring.io/spring-cloud-static/spring-cloud-contract/1.1.2.RELEASE/#_spring_cloud_contract_wiremock

If you are running Wiremock programmatically inside JUnit tests you might run into race condition since start() is non blocking. Check official documentation here it states that in context of JUnit tests:

  • For JUnit 4.x and JUnit 5 Vintage you should use JUnit rule included in WireMock
  • For JUnit 5+ Jupiter use JUnit Jupiter extension

I'm late to the party here, but I've been struggling with the same thing several times, and while the accepted answer can work in many cases, here's the solution I came up with:

https://github.com/ThomasKasene/wiremock-junit-extension

It's a custom JUnit Jupiter extension that you put over your test class, and it'll start up the server for you, much like Spring Cloud Contract's version. The difference is that it's detached from the Spring context so it can be started before Spring spins up its context.

In my case, the static config was working locally and in our CI, until we migrated our CI to cloud.. for some reason, one test was failing, because one Spring bean initiates its cache at startup by calling a remote service, and wiremock was not available at that time.. so the cache would be empty.

why did this start to happen? I have no idea.. but after adding more logs, to track when the Spring bean was getting instantiated vs when Wiremock was being setup, I realized that the Spring beans were being reused from a previous test.

so my solution, in addition to the static config, was to add @DirtiesContext(classMode = ClassMode.BEFORE_CLASS) on my test, to make sure that the whole Spring context ws being reloaded before running the tests

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM