Repository navigation
Condition in mocks聽#115
Description
Activity
This is a great idea indeed! Do you have a specific scenario in mind that we could include in our thinking?
Reacted by Adam W贸jcikThis is a great idea indeed! Do you have a specific scenario in mind that we could include in our thinking?
TBH no. It's an idea that I got when trying to make my kid to go to sleep 馃槤. But I will think more about it 馃榿
Reacted by Waldek Mastykarzsorry for the lack of response. I did a bit more thinking on this one and:
馃敡 How the feature could work
So if we could modify a bit the
responses.jsonI was thinking it could be something like this{ "requestResponses": [ { "url": "https://customapi/project/rename", "method": "PATCH", "responses": [ { "conditions": [ { "projectId": 1 } ], "responsesBody": { "id": 1, "name": "Project 1" } }, { "conditions": [ { "projectId": 2 } ], "responseCode": 404 }, { "conditions": [], "responseCode": 500 } ] }, { "url": "https://customapi/project", "method": "GET", ... } ] }The fundamental change here is that we have a collection of possible
responsesfor eachurl. Each element in the collection would be a possible response that may be retrieved when a condition is met. If we don't have any condition added to a response then it is returned always if any other response with a condition was not met. If we have more than one response without a condition then the first is used.
The above example could be something likeif (projectId == 1) { return "{ "id": 1, "name": "Project 1" }"; } else if (projectId == 2) { return responseCode.404 } else { return responseCode.500 }So in this case if my app would request a
https://customapi/project/renamesendingprojectIdas 1 I would get a success with the object in response. If my app would request ahttps://customapi/project/renamesendingprojectIdas 2 I should get404. Otherwise I should get500馃 What for? (scenario)
Lets think of a scenario where I have an app with list of projects and I the test will rename two projects. First with
id = 1and in this case I will get a success and the test will check if the app will return a modified (renamed) object. Then the app will try to rename project withid = 2. In this case the mock will return an error and the test will check if the error response is properly handled. Currently this would need to be two separate UI tests each running with a separateresponse.jsonfile. With this improvement one UI test may be a bigger scenario.let me know what do you think? 馃檪
Thank you for sharing the additional information. One challenge that I'm seeing is that if we allow specifying multiple conditions, shall we combine them with an
andor anor? Also, I find it unclear that a single request could have multiple responses and that the condition implies matching body properties. I can imagine scenarios where you might want to match request headers as well for some APIs.How about if we did this?
{ "responses": [ { "url": "https://customapi/project/rename", "method": "PATCH", "headers": { "sdk": "foo" }, "body": { "id": 1 }, "responseBody": { "id": 1, "name": "Project 1" } }, { "url": "https://customapi/project/rename", "method": "PATCH", "body": { "id": 2 }, "responseCode": 404 } ] }Right now, we use the URL as the unique value to match responses. In this new format, we'd use a combination of URL, method, headers and body. For headers and body, we'd use partial matching: all keys and values listed under headers and body must be present in the request, but the request can contain additional keys that aren't listed in the mock.
@gavinbarron @sebastienlevert @garrytrinder In the above structure, is it clear enough that
url,method,headersandbodyrefer to request or should we consider making it clearer like:{ "responses": [ { "request": { "url": "https://customapi/project/rename", "method": "PATCH", "headers": { "sdk": "foo" }, "body": { "id": 1 } }, "response": { "body": { "id": 1, "name": "Project 1" } } } ] }Reacted by Adam W贸jcik@waldekmastykarz thanks for considering my idea and improving it 馃ぉ. your suggestion is really awesome and quite clear 馃憤.
As for multiple conditions (params in body) I would consider combining it withandnotor. When I want to use theorI will specify a differentresponsefor the samerequest.
Now when looking at thejsonI am not sure how we will handleGETmethod 馃. Currently if we want to mock a specific GET request we also add the params in theurlas well but now probably this should be refactored to give those params in thebodyright?So giving an example we may have
{ "responses": [ { "request": { "url": "https://customapi/project/rename?projectid=1", "method": "GET", "headers": { "sdk": "foo" }, "body": { "projectid": 1 } }, "response": { "body": { "id": 1, "name": "Project 1" } } } ] }or better
{ "responses": [ { "request": { "url": "https://customapi/project/rename", "method": "GET", "headers": { "sdk": "foo" }, "body": { "projectid": 1 } }, "response": { "body": { "id": 1, "name": "Project 1" } } } ] }what do you think ?
As for multiple conditions (params in body) I would consider combining it with and not or. When I want to use the or I will specify a different response for the same request.
I think that if we follow this reasoning it wouldn't be obvious on the outside and might lead to confusion. I think allowing to specify one condition is less ambiguous even if it comes at the cost of duplicating configuration.
As for your second question, GET requests don't have a body. It we really wanted to break it down, we'd need to introduce another property named query and specify the different properties in there. I'm not sure what's the benefit of that and if it doesn't lead to unnecessary complexity. I'd suggest we strive for simplicity and re-evaluate if there are blocking scenarios. Ideally, configuration should be self-explanatory and doesn't require debugging to understand which mock is applied and why.
Reacted by Adam W贸jcikIn this case for GET parameter I would go in specifying it directly in the
urland don't introduce additionalqueryproperty which would be used only when method isGET.I think that if we follow this reasoning it wouldn't be obvious on the outside and might lead to confusion. I think allowing to specify one condition is less ambiguous even if it comes at the cost of duplicating configuration.
I am also ok with that 馃憤 making it possible to specify single property is fine and if needed we may always revisit this one and try to extend and then try to rethink should it be
andororor give possibility to specify which one 馃槈
Thanks @waldekmastykarz for your comments 馃憤.Reacted by Waldek MastykarzI like the idea of matching on endpoint + body etc. I would make sure we have a
requestandresponseobject withbody,code,headers, etc. (what would we need on top of it?). It's clearer. Now, something we want to ask ourselves is if mocking "at that level" is what the Dev Proxy is all about. This feels like we go down a rabbit hole. While I understand the requirement, I'm not sure we can justify this to be part of the Dev Proxy...Thoughts?
Reacted by Waldek Mastykarz@sebastienlevert that might be true.
@waldekmastykarz could this kind of thing be done by a plugin in the future? If so I would love to work on it 馃憤@sebastienlevert that might be true.
@waldekmastykarz could this kind of thing be done by a plugin in the future? If so I would love to work on it 馃憤That's the beauty of plugins, that when something doesn't necessarily fit what we have in mind, if you have a specific use case that justifies some work, you can build your own plugin and share it with others :)
Reacted by Adam W贸jcikOk. If this is put of scope for MSGraph dev proxy, let us make this a plugin 馃檪. @waldekmastykarz are there already some docs or example for plugins in the repo?
Reacted by Waldek MastykarzYes! For the upcoming release, we changed all existing functionality into plugins. Check out the plugins project for what we've got at the moment. Detailed docs are coming soon but if you're stuck at any point, please don't hesitate to reach out.
Reacted by Adam W贸jcikOk great. I guess in that case we may close this one and as soon as find time I will start working on this one
Reacted by Waldek Mastykarz- locked and limited conversation to collaborators
on Jun 4, 2025
馃挕 Idea
What if it was possible to add a condition to a mock that it should be used only when the request contains a specific value in a specific param (either GET or POST) 馃?
Currently, I think it is almost possible for GET requests by specifying a full URL of the mock also with params like
https://test/some/reqeuest?param1=aaa. That way it will only be used when we specify alsoparam1=aaain the request right?But for a POST request, this is impossible 馃. So I was wondering if the
response.jsonstructure could have some additional property in which the developer could specify a condition when this mock will be used and the condition will be about values set in some specific param.What do you think? TBH I haven't tested the above yet but just wanted to share an idea that I just got for this tool 馃槄.
馃摑 Use Case
As for a use case, I was thinking that we may not always want every POST request to fail for the same request. Sometimes it may be required to mock a failed response only when we pass specific data together with the request 馃.