-
Notifications
You must be signed in to change notification settings - Fork 470
New issue
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
Create Custom (Mock) Interaction Semantic #1949
Comments
You can probably use an explicit interaction block to achieve what you want: https://spockframework.org/spock/docs/2.3/all_in_one.html#_explicit_interaction_blocks |
Unfortunately that’s not gonna work since Spock moves only interactions to before the |
Did you have a look at the link I provided and the sneaky little word "explicit" I used? |
Ah, sorry, missed the point. OK, I think it'll do the job for now (I'll try it now). But nevertheless, I still believe this could be a very nice feature; more specifically; number of invocations as well as auto verification. If I understand "explicit block" correctly, it doesn't help with the above limitation. LMK. Thanks. |
That's right, it just helps defining the wiremock stubs in then and get it moved to before when |
@akefirad can you provide a working end2end case of what you are currently doing and then how you'd see it working with the new feature? |
There you go demo.zip |
Another use case for this would be to just use Feign clients as the interface for the mock object. Let's say you have a Feign client like this: @FeignClient
interface FooServiceClient {
@GetMapping(path = ["/foo"])
fun getFoo(): String
} Then Ideally I would love to be able to do this: def 'subject should create a user and send verification email'() {
// This is a method similar to `Mock` of Spock,
// which returns a special mock object
def foo = WireMock(FooServiceClient)
given:
def req = someRequest()
when:
// Here the subject needs to call `http://foo-service/foo`
def res = subject.doSomething(req)
then:
res.status == 200
and:
1 * foo.getFoo() >> someFooResponse()
// Things get very interesting with the request has some params and/or body.
} |
BTW, I'm happy to work on this if you like the idea. I just need a bit of help to get rolling. LMK. |
I can't think of a good way to add generic support for this into Spock. For context, the actual mock object never knows about a defined interaction such as This does not mesh well with a framework such as WireMock, where you need to declare the interactions with WireMock beforehand instead of registering a callback to handle the interaction yourself. In your example where would the conversion of wiremock.stubFor(WireMock.get(WireMock.urlEqualTo("/bar"))
.willReturn(WireMock.aResponse()
.withStatus(200)
.withBody("Hello from WireMock!")))
wiremock.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/bar"))) |
I see. Well I’m not sure. Initially I was thinking maybe the actual WireMock stubs get created by the mock object. But according to your explanation it wouldn’t be possible. Is there a way to extend |
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:
Now ideally in a (integration) test of the feature I'd love to be able to write something like this:
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 thethen
block. This becomes even uglier for tests with multiplewhen
/then
blocks, since thegiven
block is a singleton, the next batch of wiremock stubs (needed for the nextwhen
block) has to either live in thegiven
block (which is too far away from the feature being tested; hence less maintainability) or in the relevantwhen
block (which decreases the readability).Additional context
Let me know if there's anything I need to provide. Thanks.
PS: Great job BTW 👏 !
The text was updated successfully, but these errors were encountered: