I have a project on Sails.js 1
I try to use TDD on development, so I've added route testing. To prevent real API call in helpers I've mocked them via sinon
So I can successfully pass tests with this code
action2 controller code
module.exports = {
friendlyName: 'Some action',
description: '',
inputs: {
requiredParam: {
example: 'some_value',
required: true,
type: 'string',
}
},
exits: {
someError: {
description: 'Handles some error happens in controller',
message: 'Some error handled in controller',
}
},
fn: async function (inputs, exits) {
const someProcesses = await sails.helpers.someHelper(inputs.requiredParam);
if (someProcesses === 'someError') {
exits.someError(someProcesses);
} else {
exits.success(someProcesses);
}
}
};
Helper code
module.exports = {
friendlyName: 'Some helper',
description: '',
inputs: {
requiredParam: {
example: 'some_value',
required: true,
type: 'string',
}
},
exits: {
someError: {
description: 'Just some error happens in workflow',
message: 'Some error happens!',
}
},
fn: async function (inputs, exits) {
// All done.
return inputs.requiredParam === 'isError' ? exits.success('someError') : exits.success('someProcessedValue');
}
};
test code
const request = require('supertest');
const {createSandbox} = require('sinon');
describe('GET /some-page/some-action', () => {
before(() => {
this.sandbox = createSandbox();
this.sandbox.stub(sails.helpers, 'someHelper')
.withArgs('some_value').returns('someProcessedValue')
.withArgs('isError').returns('someError');
});
after(() => {
this.sandbox.restore();
});
it('should response OK', async () => {
await request(sails.hooks.http.app)
.get('/some-page/some-action')
.query({requiredParam: 'some_value'})
.expect(200);
});
it('should response with error', async () => {
await request(sails.hooks.http.app)
.get('/some-page/some-action')
.query({requiredParam: 'isError'})
.expect(500);
});
});
Then I've read on the official doc helper page that we should use exits
and intercept
to correctly handle errors from helpers on Sails.js 1.
So I've rewritten my action2 and helper to its usage and got next
Action2 controller with action2 intercept handling
module.exports = {
friendlyName: 'Some action',
description: '',
inputs: {
requiredParam: {
example: 'some_value',
required: true,
type: 'string',
}
},
exits: {
someError: {
description: 'Handles some error happens in controller',
message: 'Some error handled in controller',
}
},
fn: async function (inputs, exits) {
const someProcesses = await sails.helpers.someHelper(inputs.requiredParam)
.intercept('someError', exits.someError);// Error happens here
return exits.success(someProcesses);
}
};
Helper with exit triggering
I noticed this is problematic to test action2 controllers with preventing real helpers calls, cause when we stub helper methods using we got an error on next chained call but without these calls we can't user recommended error handling.
While I haven't used chained machine methods (tolerate
, intercept
etc) all test passes successfully, but when I affect it, I got an error.
Error
error: Sending 500 ("Server Error") response: TypeError: sails.helpers.someHelper(...).intercept is not a function
I've prepared a repo on GitHub if someone wants to try some idea.
Repo tags
- correct-test-result-without-chained-helper-methods - tests without reverse
- broken-tests-with-chained-methods - broken tests.
Here is a related question but it is for Sails.js 0.12.14-
Any idea how to avoid this problem? I will appreciate any answer.