Description
Is your feature request related to a problem?
I'd like to be able t define a custom (mock) interaction semantic for mocking external resources (e.g. MockServer or WireMock) in the then
block.
Describe the solution you'd like
As a very simple example, let's say we have user-service which depends on email-service while creating a user for sending email-verification message to the user (i.e. an API call to email-service to send a verification email to the user email address). In a unit test the spec would be something like this:
def 'subject should create a user and send verification email'() {
given:
// EmailServiceClient is a feight client poining to email-service
def emailService = Mock(EmailServiceClient)
def subject = new UserService(emailService)
def req = aCreateUserReq()
when:
def res = subject.createUser(req)
then:
res.status == 200
and:
1 * emailService.sendVerificationEmail(_)
}
Now ideally in a (integration) test of the feature I'd love to be able to write something like this:
def 'subject should create a user and send verification email'() {
given:
def req = aCreateUserReq() // Now subject is a real bean injected into the test!
when:
def res = subject.createUser(req)
then:
res.status == 200
and:
1 * wiremock.sendVerificationEmail(_) // sendVerificationEmail is just a helper method creating the WireMock stub!
}
Currently this is not gonna work, clearly! For start wiremock
is not a mock object, and also the semantic of the interaction mocking is a bit different (in this case, the stub needs to be created right away, i.e. calling WireMock).
Theoretically this should be possible I think, but I don't have deep knowledge about Spock inner details to come up with a solution. Best case scenario is to support both subbing and verification, but for start we can focus on the stubbing part.
Describe alternatives you've considered
Currently I'm putting all wiremock stubs in the given
block which is not idea since the rest of the mocks are in the then
block. This becomes even uglier for tests with multiple when
/then
blocks, since the given
block is a singleton, the next batch of wiremock stubs (needed for the next when
block) has to either live in the given
block (which is too far away from the feature being tested; hence less maintainability) or in the relevant when
block (which decreases the readability).
Additional context
Let me know if there's anything I need to provide. Thanks.
PS: Great job BTW 👏 !