How can you test that the proper event handler was called after specific event was emitted by an endpoint? (E2E integration test)
It looks like jest does not call EventEmitter2 handlers.
Thx.
Related
In the project we are building, there is a standard sequence in the workflow.
Controller receives a request
Then fires an event through #nestjs/event-emitter
Event listener listens to it and executes some code depending on the event
How can we properly test if an event has been triggered but without actually executing the code inside?
We are using Jest for testing.
Mocking with Jest doesn't seem to work, because we want to test the actual trigger event and not the result.
Any suggestions?
"node": "16.14.2"
"#nestjs/event-emitter": "^1.1.0",
"jest": "^27.5.1",
Following the suggestion from #ovidijus-parsiunas we managed to spy on the "OnEvent" method successfully.
it.only("start selling", async () => {
const user = await userSeeder.createOne();
const spy = jest
.spyOn(StartSellingListener.prototype, 'startSelling')
.mockImplementation(() => null);
expect(eventEmitter.hasListeners(EventsEnum.USER_START_SELLING)).toBe(true);
const startSelling = userService.startSelling(user);
expect(startSelling).toBeTruthy();
expect(spy).toBeCalledWith(user);
spy.mockRestore();
});
You will have to spy on the handler method that listens to the event or alternatively spy on the encapsulated methods that get called within it. Once your spies are set up you should then be able to trigger the event emitter code from your test and validate if the spies have been triggered.
I have an AWS Lambda application built upon an external library that contains an EventEmitter. On a certain event, I need to make a HTTP request. So I was using this code (simplified):
myEmitter.on("myEvent", async() => {
setup();
await doRequest();
finishingWork();
});
What I understand that happens is this:
My handler is called, but as soon as the doRequest function is called, a Promise is returned and the EventEmitter continues with the next handlers. When all that is done, the work of the handler can continue (finishingWork).
This works locally, because my NodeJS process keeps running and any remaining events on the eventloop are handled. The strange thing is that this doesn't seem to work on AWS Lambda. Even if context.callbackWaitsForEmptyEventLoop is set to true.
In my logging I can see my handler enters the doRequest function, but nothing after I call the library to make the HTTP call (request-promise which uses request). And the code doesn't continue when I make another request (which I would expect if callbackWaitsForEmptyEventLoop is set to false, which it isn't).
Has anyone experienced something similar and know how to perform an ansynchronous HTTP request in the handler of a NodeJS event emitter, on AWS Lambda?
I have similar issue as well, my event emitter logs all events normally until running into async function. It works fine in ECS but not in Lambda, as event emitter runs synchronously but Lambda will exit once the response is returned.
At last, I used await-event-emitter to solve the problem.
await emitter.emit('onUpdate', ...);
If you know how to solve this, feel free to add another answer. But for now, the "solution" for us was to put the eventhandler code elsewhere in our codebase. This way, it is executed asynchronously.
We were able to do that because there is only one place where the event is emitted, but the eventhandler way would have been a cleaner solution. Unfortunately, it doesn't seem like it's possible.
I have a Logic App invoking a Function App. The Function App may fail, and if it does, I want the Logic App to do it's retry thing. But I don't know what is the correct way of conveying failure back to the Logic App. My Function App signature is
public static async Task Run(...)
Is throwing an exception the only option? I assume there's a better way, as I want to Logic App to get back my out params even if the Function App fails.
The logic app calls your function app via webhook, so by throwing an exception you send an error http response back to logic apps.
You could, upon detecting an error in the function, create and return an error response yourself. Here's some documentation on logic app error handling, it might have info on the parameter handling you're hoping for: https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-exception-handling
I wrote a TCP server using Node.js and on my tests (with Mocha) I'm testing that the server actually emits all the events it should. The one problem that I'm finding is that I cannot trigger the error event at will so I cannot automate this test.
socket.on('error', function()
{
// How do I test this?
});
Is there a way to trigger this event manually? O maybe craft a corrupt packet?
You can emit it manually: socket.emit('error', new Error('foo bar baz'));
Goal is:
Get comet message to work with overridden methods in controller like UPDATE or CREATE or DESTROY.
When i don't do override in controller SailsJS for UPDATE, i get comet message when i say socket.on('message').
Code is this:
#listening socket for new apps
socket.on "message", (data) ->
console.log data
if data.model is "application"
viewModel.apps.push(new App(data.data))
if data.model is "configuration"
#rewrite this
return
But this is never fired when i override method in my case UPDATE.
No matter what res i return never fires it up, I'm using res.json().
Thanks
Take a look at the blueprint hook for update, you have to handle the pub/sub of models for your custom routes.
https://github.com/balderdashy/sails/blob/master/lib/hooks/blueprints/actions/update.js
You need to call Model.publishUpdate and Model.subscribe