FromCallbackScenario is a Module Scenario that allows you to test all of the business requirements of a given module, function, or section of code. You should use this module when your entry point function returns its results through a callback.
We saw with the HttpRequestScenario, that it was able to test the response itself. This isn't possible with Module Scenarios. With the Module Scenarios, you will need to provide a function to test the results yourself. You do this by passing your function into the .test function. You can see an example of this below.
Important Notes
- You do NOT provide a callback in your inputParams. Maddox will automatically provide a function as the last parameter into your entry point function.
- Below there are only two parameters passed into the testing function. Rest assured, the FromCallbackScenario will pass all of the parameters expected in your callback.
- You will see that our DB Proxy is still returning a Promise. This doesn't mean that our module must return a promise though. You can see here that we can still test a callback scenario when lower level proxy functionality returns a Promise or synchronously.
const Maddox = require("maddox");
const Scenario = Maddox.scenarios.FromCallbackScenario;
describe("When testing a function that uses a callback.", () => {
let context;
beforeEach(() => {
context = {};
context.setupEntryPoint = () => {
context.entryPointObject = MyModule; // The entry point of our module.
context.entryPointFunction = "entryPoint";
};
context.setupInputParams = () => {
context.inputParams = {
dataToSave: {foo: "foo"}
};
};
context.setupDbProxy = () => {
// When reusing parameters it is best practice to copy them to ensure the referenced data changes are not causing...
// unexpected errors in your tests. Maddox will do this for you, but it is good to make it obvious in your test.
context.dbProxyParams = JSON.parse(JSON.stringify(context.inputParams));
context.dbProxyResponse = {code: 200};
};
context.setupExpected = () => {
context.expectedResponse = {success: true};
context.expectedStatusCode = 200;
};
});
it("it should send data to the database.", function (done) {
context.setupEntryPoint();
context.setupInputParams();
context.setupDbProxy();
context.setupExpected();
new Scenario(this)
.mockThisFunction("DbProxy", "save", DbProxy)
.withEntryPoint(context.entryPointObject, context.entryPointFunction)
.withInputParams([context.inputParams])
.shouldBeCalledWith("DbProxy", "save", [context.dbProxyParams])
.doesReturnWithPromise("DbProxy", "save", context.dbProxyResponse)
.test(function (err, response) {
Maddox.compare.shouldEqual({actual: err, expected: undefined});
Maddox.compare.shouldEqual({actual: response, expected: testContext.expectedResponse});
done();
}).catch(function (err) {
done(err);
});
});
it("it should process the error from the database.", function (done) {
context.setupDbProxy = () => {
const dbError = new Error("Failed to save data.");
dbError.code = 12345;
// When reusing parameters it is best practice to copy them to ensure the referenced data changes are not causing...
// unexpected errors in your tests. Maddox will do this for you, but it is good to make it obvious in your test.
context.dbProxyParams = JSON.parse(JSON.stringify(context.inputParams));
context.dbProxyResponse = dbError;
};
// Let's pretend that our code returns the error code from the db in our response when the database fails.
context.setupExpected = () => {
context.expectedResponse = {success: true, code: 12345};
context.expectedStatusCode = 500;
};
context.setupEntryPoint();
context.setupInputParams();
context.setupDbProxy();
context.setupExpected();
new Scenario(this)
.mockThisFunction("DbProxy", "save", DbProxy)
.withEntryPoint(context.entryPointObject, context.entryPointFunction)
.withInputParams([context.inputParams])
// Notice that we have changed this to "doesErrorWithPromise" instead of "doesReturnWithPromise"...
// since we are testing a scenario for the DbProxy to error.
.shouldBeCalledWith("DbProxy", "save", [context.dbProxyParams])
.doesErrorWithPromise("DbProxy", "save", context.dbProxyResponse)
.test(function (err, response) {
Maddox.compare.shouldEqual({actual: err, expected: undefined});
Maddox.compare.shouldEqual({actual: response, expected: testContext.expectedResponse});
done();
}).catch(function (err) {
done(err);
});
});
});