I have this case where I think I want to have nested it()
test cases in a Mocha test. I am sure this is wrong, and I don't see any recommendations to do what I am doing, but I don't really know of a better way at the moment -
basically, I have a "parent" test, and inside the parent test there's a forEach loop with all the "child" tests:
it('[test] enrichment', function (done) {
var self = this;
async.each(self.tests, function (json, cb) {
//it('[test] ' + path.basename(json), function (done) {
var jsonDataForEnrichment = require(json);
jsonDataForEnrichment.customer.accountnum = "8497404620452729";
jsonDataForEnrichment.customer.data.accountnum = "8497404620452729";
var options = {
url: self.serverURL + ':' + self.serverPort + '/event',
json: true,
body: jsonDataForEnrichment,
method: 'POST'
};
request(options,function (err, response, body) {
if (err) {
return cb(err);
}
assert.equal(response.statusCode, 201, "Error: Response Code");
cb(null);
});
//});
}, function complete(err) {
done(err)
});
});
as you can see, two separate lines are commented out - I want to include them so that I can easily see the results of each separate test, but then I have this awkward situation of firing the callback for the test alongside the callback for async.each.
Has anyone seen this time of situation before and know of a good solution where the tester can easily see the results of each test in a loop?
Don't nest it
calls. Call them synchronously.
Nested it
calls are never okay in Mocha. Nor are it
calls performed asynchronously. (The test can be asynchronous, but you cannot call it
asynchronously.) Here's a simple test:
describe("level 1", function () {
describe("first level 2", function () {
it("foo", function () {
console.log("foo");
it("bar", function () {
console.log("bar");
});
});
setTimeout(function () {
it("created async", function () {
console.log("the asyncly created one");
});
}, 500);
});
describe("second level 2", function () {
// Give time to the setTimeout above to trigger.
it("delayed", function (done) {
setTimeout(done, 1000);
});
});
});
If you run this you won't get the nested test bar
will be ignored and the test created asynchronously (delayed
) will also be ignored.
Mocha has no defined semantics for these kinds of calls. When I ran my test with the latest version of Mocha at the time of writing (2.3.3), it just ignored them. I recall that an earlier version of Mocha would have recognized the tests but would have attached them to the wrong describe
block.
I think the need for dynamic tests are relatively common (data-driven tests?), and there is common use for dynamic it
and test cases.
I think it could be easier to manage testcase completion if tests could be executed in series. This way you wouldn't have to worry about managing nested async done
's. Since request
is async (i'm assuming), your test cases will still mainly be executing concurrently.
describe('[test] enrichment', function () {
var self = this;
_.each(self.tests, function (json, cb) {
it('[test] ' + path.basename(json), function (done) {
var jsonDataForEnrichment = require(json);
jsonDataForEnrichment.customer.accountnum = "8497404620452729";
jsonDataForEnrichment.customer.data.accountnum = "8497404620452729";
var options = {
url: self.serverURL + ':' + self.serverPort + '/event',
json: true,
body: jsonDataForEnrichment,
method: 'POST'
};
request(options,function (error, response, body) {
if (error) {
cb(error);
}
else{
assert.equal(response.statusCode, 201, "Error: Response Code");
cb(null);
}
done();
});
});
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With