One thing I’ve noticed while looking at the generators for both yeoman and slush, is that overall, they tend to be undertested. I think this is for two reasons. Firstly, I think many folks consider this kind of dev tool to not be, generally speaking, differnt from production code. Its a tool to assist a dev work, and not necessarily subject to the same level of testing rigor. I think anothe reason is that testing file IO is fundamentally much more challengin then a typical unit test.
Thankfully, since we are testing gulp output, theres a handy module that does make things easier called
mock-gulp-dest. If you look at the source of
mock-gulp-dest, you’ll notice that it uses
through2 to essentially handle the mocking of the file IO. Of course you don’t want to actually write files to the disk and assert their existance. It might be tempting to use one of the
fs assertion tools and actually put the files somethere, but that’s pretty messy in the long run, and not pragmatic for running tests in multiple environments. Rather,
mock-gulp-dest actually stubbs the
dest method with one that doesn’t actually write, and then reverts it when complete. That said, this is ultimately a sophisticated function stub.
Firstly, its handy to make a fixture to mock the inquirer output.
This is the contents of an inquirer fixture that handles that well. Once you have that, just include it in your test files where you are going to mock the prompts. You’ll also want to include the actual slushfile you’re testing. In this case, imagine there is just one main slushfile to test:
var mockPrompt = require('./inquirer-prompt-fixture');
To my taste, I am partial to mocha for a test runner and chai’s expect syntax for assertion. YOu can use whatever you want, but this is what I use.
Here is an example fo a file performing two simple tests:
Now for a description of the tricky part. The file writing is essentially an async process. You’ll need to use a testing framework that can elegantly handle an async assertion with a callback. In this case, its idiomatic in
mocha to use done in this manner. You can use
gulp.start('yourtaskname') to kick off a stask, but the very important part is that you attach the assertion to the handler of
task_stop. Be wary, you might see
on('stop') or other variants in other folk’s code. If you use
on, you might get some errors in your runner, such as
Error: done() called multiple times
Or if you attach to a differnt event, your runner will fail because it times out, because the asserting function never gets called at all (and hence the
done function never is called).
To test, I cam calling my testing method from gulp. Its pretty straightforward in the gulpfile.
So to actually run the test, I call
I always use the nyan cat reporter, because it delights me.
No judging here.
Watch that kitty surf that poptart!!!
[22:37:41] Starting 'test'...
Oh nice! We got two passing tests! Could use a few more though :)