Closed janonymus closed 6 years ago
As it currently stands it is not possible to override an expectation that has already been setup, by design. The expectations are evaluated in the order they are setup so if two expectations match exact then the first one will always be matched. However if the first expectation is only valid for a limited number of matches once it has completed the specified number of matches the second matching expectation will be matched. As follows:
{
"httpRequest": {
"method": "GET",
"path": "/simple"
},
"httpResponse": {
"statusCode": 200,
"body": "some response - one"
},
"times": {
"remainingTimes": 3,
"unlimited": false
}
}
{
"httpRequest": {
"method": "GET",
"path": "/simple"
},
"httpResponse": {
"statusCode": 200,
"body": "some response - two"
},
"times": {
"remainingTimes": 1,
"unlimited": true
}
}
/simple
and get the following sequence of responsesome response - one
some response - one
some response - one
some response - two
some response - two
some response - two
some response - two
...
I have just re-tested this manually and it works as expected. There are also multiple tests covering these cases, such as org.mockserver.mock.MockServerMatcherSequentialResponsesTest
and org.mockserver.mock.MockServerMatcherOverlappingRequestsTest
.
Perhaps you could provide some code examples so that I can better understand what the issue is.
Thanks for your response!
Imagine that you have a "button" which you press would change the state of the server, but until it's not pressed the state should be always "A" and after pressed the state should be always "B".
Setup for "state A"
{ "httpRequest": { "method": "GET", "path": "/simple" }, "httpResponse": { "statusCode": 200, "body": "state - A" }, "times": { "remainingTimes": 3, "unlimited": false } }
After the button is "pressed" we run the set up for state B
Setup for "state A"
{ "httpRequest": { "method": "GET", "path": "/simple" }, "httpResponse": { "statusCode": 200, "body": "state - B" }, "times": { "remainingTimes": 3, "unlimited": false } }
In this case we want this result: state - A state - A state - A "button pressed, setup for state B is executed" state - B state - B state - B
What we usually get is like this: In this case we want this result: state - A state - A state - A "button pressed, setup for state B is executed" state - A state - B state - B
Have you thought of mocking each request one by one?
The other option is you might need to wait until I have finished the websocket callback logic, this is complete but still needs a couple more integration tests and the javascript client, see branch websocket_callbacks. This would allow you to dynamically define a response using a local callback method in the test. For example:
mockServerClient
.when(request().withPath("/object_callback"))
.callback(
new ExpectationCallback() {
@Override
public HttpResponse handle(HttpRequest httpRequest) {
return response()
.withStatusCode(HttpStatusCode.ACCEPTED_202.code())
.withHeaders(
header("x-object-callback", "test_object_callback_header")
)
.withBody("an_object_callback_response");
}
}
);
In Java 7 with lambas this code would look much nicer as follows:
mockServerClient
.when(request().withPath("/object_callback"))
.callback(
httpRequest -> response()
.withStatusCode(HttpStatusCode.ACCEPTED_202.code())
.withHeaders(
header("x-object-callback", "test_object_callback_header")
)
.withBody("an_object_callback_response")
);
Under the hood a websocket is opened between the MockServerClient and MockServer so that when MockServer receives a matching request the MockServer communicates back to the MockServerClient using the websocket to retrieve the response that should be returned.
I would expect this to be in the next release in one to two weeks from now.
Hi,
Great work on this project!
About this specific question, I'll try to add my scenario: I'm trying to set the "right" expectation for my http client, and it's always an unlimited in count. This kind of process is trial and error, mostly since I'm trying to figure out the best response. So the matching is always the same, but the response might change during the process.
In my experience, if I change the expectation, then the previous one is still there, for a single request.
But I want to completely override the current expectation with the new one, as documented.
Is it possible to change the behavior of mock-server to override the exact previously configured expectations?
The easiest way to do this would be to clear the previously configured expectations, then create a new expectation.
I am going to close this ticket as the documentation has been update (90% completed).
Hi ,
I'm looking for a way to match unknown number of requests within 60 seconds then remove expectation I have the following in expectation : "times": { "unlimited": false }, "timeToLive" : { "timeUnit" : "SECONDS", "timeToLive" : 60, "unlimited" : false }
But this results in matching the expectation only once and then it is removed without waiting for the 60 seconds to finish. if I change it to : "times": { "unlimited": true }, "timeToLive" : { "timeUnit" : "SECONDS", "timeToLive" : 60, "unlimited" : false }
Then the expectation won't be removed even after 60 seconds Any idea ? Thanks
Imagine that I'm setting up an unlimited response for /test to say message "A" then overriding the same path with message "B"
for the first few times calling that path, I receive message "A" for the first few times. Only after calling the same path a few times I'm able to get the overridden message "B"
Is there any workaround for this?