Open williamgcampbell opened 8 hours ago
This makes it difficult to test behavior
Is there anything why you can not do this:
await expect(
() => testMiddleware( /* ... */ )
).rejects.toThrow("something went wrong");
// and then check logs too
expect(loggerMock._getLogs().info).toHaveLength(1);
https://vitest.dev/api/expect.html#rejects https://vitest.dev/api/expect.html#tothrowerror
@williamgcampbell ?
My point is that you don't need catchErrors: true
because there are already established methods of testing frameworks for asserting expectations on thrown errors.
testMiddleware()
just calls Middleware::execute()
that calls the specified handler
.
Therefore, if that one throws, testMiddleware()
throws as well, so you could use standard testing approach here.
await expect(
() => testMiddleware( /* ... */ )
).rejects.toThrow("something went wrong");
// and then check logs too
expect(loggerMock._getLogs().info).toHaveLength(1);
In this example how do you gain access to loggerMock
? It is initialized and returned by testMiddleware
. The same goes for the request mock and response mock, which are all lost to the calling test if an exception is thrown.
Ah! I get what you mean now, thank you for clarifying the problem, @williamgcampbell
and return them in the response
it's a good idea, but I'd recommend to devote to consumer to decide how exactly that should happen. So that it would be configurable.
Therefore, I'm suggesting to extend your idea slightly, @williamgcampbell :
- catchErrors?: boolean
+ errorHandler?: (error: Error, response: Response) => void;
So, that errorHandler
will act BOTH as a flag for catching AND as an implementation of responding with the error somehow.
In basic scenario it can be:
(error, response) => response.end(error.message)
What do you think?
Here is my final implementation, @williamgcampbell in #2154 :
I believe it should solve the issue for your case. Let me know how you feel about it.
It's common for middleware to throw exceptions when validating auth tokens or other request information. When this happens, the mocks available within
testMiddleware
won't be returned and can't be used to confirm behavior. This makes it difficult to test behavior of anything that happened up to the point of failure. For example:To implement this we could provide an extra field to the function to indicate the intention of getting an error response back. Something like: