spring-projects / spring-boot

Spring Boot
https://spring.io/projects/spring-boot
Apache License 2.0
74.99k stars 40.66k forks source link

Investigate wiremock #5173

Open philwebb opened 8 years ago

philwebb commented 8 years ago

Can we make it easy to integrate. Random port with Rest calls for example.

snicoll commented 8 years ago

There is a discussion on Twitter when we compare wiremock and our own MockRestServiceServer. I don't think there's much to do for the latter but it would be nice to check nevertheless.

wilkinsona commented 8 years ago

A REST Docs user was investigating writing out Wiremock JSON snippets. Not sure how, if at all, that may fit here. /cc @otrosien

otrosien commented 8 years ago

Haven't gotten around looking at the latest changes in restdocs. The integration of wiremock in a rest client test is already pretty simple as-is: Just instanciate a WireMockRule in your test code. But the interesting part is, how to get a server-generated mock response (in our case by writing and jarring a wiremock json-snippet via restdocs) into the client test. That's where we currently have working code, which I'd like to pour into a pull request in the near future.

jkubrynski commented 8 years ago

I remember @dsyer and @spencergibb have done some investigation here by using https://github.com/Codearte/accurest with RestDocs. AccuREST is already handling Wiremock stubs generation. Here is the sample: https://github.com/spencergibb/spring-cloud-dependencies-sample //cc @marcingrzejszczak

poznachowski commented 8 years ago

I have implemented Wiremock + Rest Assured within a Spring Boot starter lately. However, it is currently based on using Feign and Ribbon. It's available here: https://github.com/neoteric-eu/neo-starters/tree/master/neo-starter-test/src/main/java/com/neoteric/starter/test

philwebb commented 8 years ago

Thanks everyone for the comments and suggestions.

otrosien commented 8 years ago

@philwebb there's one more thing that can be improved: Firing up a wiremock server on a random port and wiring its address to ribbon/resttemplate can potentially be stream-lined.

wilkinsona commented 8 years ago

The difficulty of getting and using WireMock's random port came up on Slack today with Andrew Thorburn from Pivotal Labs.

poznachowski commented 8 years ago

@wilkinsona Could you say a little more?

wilkinsona commented 8 years ago

@poznachowski WireMock's server was being configured to start on a random port. The goal was to then inject that port into some code that's making HTTP calls so that it talks to the WireMock server rather than the actual service. That was proving tricky (in part due to the use of field injection), but I think there's room for Boot to make it easier, perhaps by exposing a property for the port as we do with local.server.port.

marcingrzejszczak commented 8 years ago

I've created a new feature in AccuREST called Stub Runner. If you publish the WireMock stubs into a Maven repository you can then use Stub Runner to download those stubs and run them as WireMock servers in your tests.

You can use a JUnit rule to do that:

@ClassRule public static AccurestRule rule = new AccurestRule()
            .repoRoot("http://your.repo.com")
            .downloadStub("io.codearte.accurest.stubs", "loanIssuance")
            .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer");

    @Test
    public void should_start_wiremock_servers() throws Exception {
        // expect: 'WireMocks are running'
            then(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")).isNotNull();
            then(rule.findStubUrl("loanIssuance")).isNotNull();
            then(rule.findStubUrl("loanIssuance")).isEqualTo(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance"));
            then(rule.findStubUrl("io.codearte.accurest.stubs:fraudDetectionServer")).isNotNull();
        // and:
            then(rule.findAllRunningStubs().isPresent("loanIssuance")).isTrue();
            then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs", "fraudDetectionServer")).isTrue();
            then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs:fraudDetectionServer")).isTrue();
        // and: 'Stubs were registered'
            then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance");
            then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer");
    }

or you can use Spring support

@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader)
class StubRunnerConfigurationSpec extends Specification {

    @Autowired StubFinder stubFinder

    def 'should start WireMock servers'() {
        expect: 'WireMocks are running'
            stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null
            stubFinder.findStubUrl('loanIssuance') != null
            stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance')
            stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null
        and:
            stubFinder.findAllRunningStubs().isPresent('loanIssuance')
            stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer')
            stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer')
        and: 'Stubs were registered'
            "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
            "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
    }

    @Configuration
    @Import(StubRunnerConfiguration)
    @EnableAutoConfiguration
    static class Config {}
}

We're planning on adding Spring Cloud support so that the WireMocks can get automatically registered / found in a provided service discovery.

otrosien commented 8 years ago

@philwebb we also implemented a custom spring-boot-starter for wiremock [1]. We added a property wiremock.port that you could use in a SpEL for pointing the clients to wiremock.

[1] https://github.com/ePages-de/restdocs-wiremock#how-to-use-wiremock-in-your-client-tests

marcingrzejszczak commented 8 years ago

BTW we've done some integration already in Spring Cloud Contract Wiremock - https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_spring_cloud_contract_wiremock