I’m writing down some of the things I’ve picked up when I started to learn about Node, Express and Mongo. Here are all the post in the series:
- Doing stuff in the terminal is not scary at all
- npm is not only for getting packages
- Package.json is a mighty tool
- Git is not that hard, but I need to refresh my knowledge
- Callback function is cool stuff, and I even know how to write them
- mocha is cool both as framework and test runner
- Should is a nice way to do asserts - this post
- monk is an easy way to access mongo
- Express is best without generators
- supertest is a nice way to test an api
This post is about an assertion framework that I’ve come to love; should.js.
The thing with most Node packages is that they are quite small, often around 100-200 lines. They, in turn, make use of other packages in the form of dependencies. This is a good thing and leads both to modularity, better design (maybe…) but gives you the opportunity to stitch together an environment just like you like it. Never is this better displayed than when writing tests.
Not only is there a plethora of testing framework to choose from, equally many test runners that can run them, mocking frameworks but also separate assertion frameworks. This is not news to me (I love ShouldFluent when writing C# for example) and makes for a very customisable experience.
The assertion framework that I’ve ended up using is called should.js. Finally a framework that has a name that reveals something of it’s usage and syntax.
It’s easily installed with npm, of course
npm install should
and you’re ready to use the should assertions in your test code. Oh well you need to:
var should = require(“should”);
in your test file of course.
The full list of the assertions that is supported can be found here but here’s the ones that I’ve (you might like others…) come to use a lot:
- hey, I don’t need to explain them. How is that for a great demonstration of the use of readable syntax…
- x.should.startWith(“a string”)
- not - just negates the assertions. x.should.not.be.equal(y) for example.
In fact, there’s an whole array (.an, .of, .a, .and, .be, .have, .with, .is, .which) of those conjunctions that you could add for readability. Like this example:
I have only used not so far, but I could see that some of the others might be useful.
The trip upsThe things I often forget
There are a few problems that I keep running into. It’s not very flattering for my intelligence that I keep doing it over and over but I thought I’d write it down so that at least know how to fix it the next time.
Assert for null and undefined
If you’re checking that something is null or not, you’re at a bit of loss, since should cannot attach any extension methods to null (since that’s no object I presume). In these cases you need to write the should as a standalone, global method. Here’s an example:
Forgetting the require
Another, very basic thing, that trips me up is that I forget to add the require statement for should in my test file. I presume I forget this since you don’t have to add one for mocha. My feeble mind seems to reason “Hey, great! In tests we apparently don’t need to add any requires.” Let’s say you have the following assertion:
If you don’t add the require-statement for should you’ll end up with an error message like this:
“TypeError: Cannot call method ‘equal’ of undefined”
Luckily it’s easy fixed. Add this at the top of your test-file:
var should = require(“should”);
“This way assert you should” - Yoda (and Rob Conery)
One last thing that I’ve found very useful. In the testing episode of the excellent TekPub series on Angular Rob Conery have a short little part on how he writes assertions (or it-functions in the case of mocha et al). I have done the same journey as he and picked up, what he calls, the Yoda way.
Up to then I used to write:
it(“should be defined”), it(“should validate presence of email”)
But really why put the “should” in there? In the immortal words of Yoda:
Or in our case:
Do or do not. There is no should!
And just removing the “should” from the assertions clears them up quite a lot.
it(“is defined”) it(“validates presence of email”)
This also makes for nicer reports, like this: