This is a question regarding asynchronoust testing in Sails JS using Mocha.
I am writing controller test in Sails JS using supertest library. I want to check if a method is being called on HTTP POST to our controller. For that, I am stubbing the method and expecting it to be invoked in the end() as follows:
request(sails.hooks.http.app)
    .post('heartbeat/create')
    .send('device: 1')
    .end(function(err, res) {
        expect(publishCreateStub.called).to.be.true;
        done();
    });
When I run this, the expectation fails because the method is not called when asserting. But when I put the expectation in a setTimeout as follows, it works:
request(sails.hooks.http.app)
    .post('heartbeat/create')
    .send('device: 1')
    .end(function(err, res) {
        setTimeOut(function() {
            expect(publishCreateStub.called).to.be.true;
            done();
        }, 1000);
    });
Is there any way to make the test pass without a setTimeout?
Here is the code part I am testing: HeartbeatController#create
You can also help us to resolve the issue by sending pull requests: https://github.com/multunus/one-mdm/issues/1
                        
The actual problem is that your controller don't wait for
publishCreateto be called. So, you're responding with201 Createdwithout checking that anything was created.There is a chance that either
Heartbeat.findOneorHeartbeat.publishCreatewill fail, but you'll newer know it.To fix this problem you should modify your controller, moving response part inside
Heartbeatpromise callback:In my example I'm delegating an actual error handling to the next express error-handling middleware:
But you may decide to handle the error yourself instead, e.g.: