mockttp icon indicating copy to clipboard operation
mockttp copied to clipboard

Question: How do you delete individual replies ?

Open SilentM0ng00se opened this issue 3 years ago • 3 comments

My use case is currently as follows:

  1. I create a mockttp server on some port
  2. I create replies for paths and match specific fields in the headers

How do I go about deleting individual replies in place i.e without using reset() ?

Example Code :

const mockserver = require('mockttp').getLocal();

async function runServer(){

    await mockserver.start(3001);

    await mockserver.forGet("/sample/request").withHeaders({"id" : '0000'}).thenReply(200, JSON.stringify({
        "headers": {
            "id": "0000"
        },
        "statusCode": 200,
        "body": "response 0000"
    }))

    // How would you go about deleting this rule on the fly ?
    await mockserver.forGet("/sample/request").withHeaders({"id" : '0001'}).thenReply(200, JSON.stringify({
        "headers": {
            "id": "0001"
        },
        "statusCode": 200,
        "body": "response 0001"
    }))
}
runServer()

SilentM0ng00se avatar Apr 12 '22 16:04 SilentM0ng00se

This isn't especially well supported, since it's usually better (clearer and easier to maintain) if you define your rules up front, without them changing dynamically later.

There are a couple of options for this though, depending on what you want:

  • If you know in advance exactly how many times that rule should run, it's best to use forGet(...).once(), .twice() or .times(n) to declaratively control how much rules run in advance. I'd be open to PRs to add more methods here like .until((req) => ...) or something if that would be useful.
  • If you want to freely implement changing behaviour for a single rule, you can use .thenCallback(req => req) to control behaviour directly with your own callback.
  • If you want to fully control the set of rules yourself, you can manually construct and modify rules by:
    • By building rule data from matchers (Mockttp.matchers.*), completion checkers (Mockttp.completionCheckers.*) and handler definitions (Mockttp.requestHandlerDefintions.*)
    • Passing those to mockserver.setRequestRules.
    • You can then modify your rule data and call that method again to update the set of rules any way you like.

Take a look through the API docs for more details on the API for all that. It's probably worth looking through the test suite too, which has plenty of detailed examples.

Does that work for you? If not, can you explain a bit more about what you're trying to do and why?

pimterry avatar Apr 13 '22 10:04 pimterry

Thanks for the detailed response! Yes this does give me an avenue to implement deletion.

I'm curious about the challenges of providing an out of the box functionality for deletion or if there are any plans in the roadmap for the future ?

SilentM0ng00se avatar Apr 14 '22 00:04 SilentM0ng00se

I'm curious about the challenges of providing an out of the box functionality for deletion or if there are any plans in the roadmap for the future?

It's not that it's especially challenging technically - it's that it's not a good API design.

For automated testing it's almost always better to define mock rule behaviour and rule expiry declaratively upfront, instead of changing it dynamically - that creates very hard to debug or understand test code.

For building proxies, it's usually easier & more effective to use a callback and explicitly describe the logic behind changing behaviour, or to rebuild & replace the entire rule set when underlying configuration changes.

Trying to add and remove rules dynamically is quite possible, but I've never yet seen a situation where it was the best solution. Happy to hear more about your use case if you think it's an exception though.

pimterry avatar Apr 14 '22 12:04 pimterry