That wasn't enough to test much, so let's go ahead and add some more tests:
describe("read note", function() {
it("should have proper note", async function() {
const note = await model.read("n1");
assert.exists(note);
assert.deepEqual({ key: note.key, title: note.title, body:
note.body }, {
key: "n1", title: "Note 1 FAIL", body: "Note 1"
});
});
it("Unknown note should fail", async function() {
try {
const note = await model.read("badkey12");
assert.notExists(note);
throw new Error("should not get here");
} catch(err) {
// this is expected, so do not indicate error
assert.notEqual(err.message, "should not get here");
}
});
});
describe("change note", function() {
it("after a successful model.update", async function() {
const newnote = await model.update("n1", "Note 1 title
changed", "Note 1 body changed");
const note = await model.read("n1");
assert.exists(note);
assert.deepEqual({ key: note.key, title: note.title, body:
note.body }, {
key: "n1", title: "Note 1 title changed", body: "Note 1 body
changed"
});
});
});
describe("destroy note", function() {
it("should remove note", async function() {
await model.destroy("n1");
const keyz = await model.keylist();
assert.exists(keyz);
assert.isArray(keyz);
assert.lengthOf(keyz, 2);
for (let key of keyz) {
assert.match(key, /n[23]/, "correct key");
}
});
it("should fail to remove unknown note", async function() {
try {
await model.destroy("badkey12");
throw new Error("should not get here");
} catch(err) {
// this is expected, so do not indicate error
assert.notEqual(err.message, "should not get here");
}
});
});
after(function() { model.close(); });
});
Notice that for the negative tests – where the test passes if an error is thrown – we run it in a try/catch block. The throw new Error line in each case should not execute because the preceding code should throw an error. Therefore, we can check if the message in that thrown error is the message which arrives, and fail the test if that's the case.
Now, the test report:
$ npm run test-notes-memory
> notes-test@1.0.0 test-notes-memory /Users/david/chap11/notes/test
> NOTES_MODEL=memory mocha test-model
Model Test
check keylist
√ should have three entries
√ should have keys n1 n2 n3
√ should have titles Node #
read note
√ should have proper note
√ Unknown note should fail
change note
√ after a successful model.update
destroy note
√ should remove note
√ should fail to remove unknown note
8 passing (17ms)
In these additional tests, we have a couple of negative tests. In each test that we expect to fail, we supply a notekey that we know is not in the database, and we then ensure that the model gives us an error.
The Chai Assertions API includes some very expressive assertions. In this case, we've used the deepEqual method which does a deep comparison of two objects. In our case, it looks like this:
assert.deepEqual({ key: note.key, title: note.title, body: note.body }, {
key: "n1", title: "Note 1", body: "Note 1"
});This reads nicely in the test code, but more importantly a reported test failure looks very nice. Since these are currently passing, try introducing an error by changing one of the expected value strings. Upon rerunning the test, you'll see:
Model Test
check keylist
√ should have three entries
√ should have keys n1 n2 n3
√ should have titles Node #
read note
1) should have proper note
√ Unknown note should fail
change note
√ after a successful model.update
destroy note
√ should remove note
√ should fail to remove unknown note
7 passing (42ms)
1 failing
1) Model Test
read note
should have proper note:
AssertionError: expected { Object (key, title, ...) } to deeply
equal { Object (key, title, ...) }
+ expected - actual
{
"body": "Note 1"
"key": "n1"
- "title": "Note 1"
+ "title": "Note 1 FAIL"
}
at Context.<anonymous> (test-model.js:53:16)
at <anonymous>
At the top is the status report of each test case. For one test, instead of a check mark is a number, and the number corresponds to the reported details at the bottom. Mocha presents test failures this way when the spec reporter is used. Mocha supports other test report formats, some of which produce data that can be sent into test status reporting systems. For more information, see https://mochajs.org/#reporters.
In this case, the failure was detected by a deepEqual method, which presents the detected object inequality in this way.