Unit testing in Keystone JS

After many annoying tests and messing about with Keystone.JS, I’ve finally managed to get a proper Unit Testing system in place.

 What am I using?

We just need two super useful plugins to get started.

 How does it work?

In our package.json we’ve added a test script that sets up Mocha.

"scripts": {
    "start": "node keystone.js",
    "test": "./node_modules/.bin/mocha tests/init.js tests/unit/**"
}

This means that when we run (or in our case, CircleCI runs) npm test we’ll automatically launch into the Mocha test process and work through our assertions.

Our init.js script is simply used to setup the environment and get everything ready that we need to run tests.

process.env.NODE_ENV = process.env.NODE_ENV || 'test';
require('dotenv').load();

var keystone = require('keystone');
var chai = require('chai');

keystone.init({
  'name': 'YourExactProjectName',
  's3 config': {} //leave this here or stuff will break (magic)
});

keystone.import('../models');

chai.should();

Once we’ve done this, we can start adding tests to our /test/unit/ directory.

In the case of our project, I’m working with this folder structure:

The primary concern for the tests is the Model, and because we’re using Mongo, our tests will be running with a live connection to the database.

Here is an example of a test:

/*
  Post Unit Test
  for Keystone.JS built-in Post Model
 */
 var keystone = require('keystone');
 var chai = require('chai');
 var dbURI = "mongodb://localhost/<< YOUR DB >>" || process.env.MONGO_URL;
             // CHANGE THIS AS NEEDED

describe('Posts', function() {
  beforeEach(function(done){
    if (keystone.mongoose.connection.db) return done();
    console.log('Connecting to ' + dbURI)
    keystone.mongoose.connect(dbURI, done);
  });

  it('should be a connection to Mongo', function(done){
    keystone.mongoose.connection.db.should.be.a('Object');
    done();
  });

  it('should be a Mongoose Model', function(done) {
    Post = keystone.list('Post');

    Post.should.be.a('Object');
    Post.should.have.property('model').be.a('Function');
    Post.should.have.property('schema').be.a('Object');

    done();
  });
});

Hopefully this will help you out with your own project. Feel free to comment if you have any difficulties and I’ll endeavour to respond with the answers!

P.S. Thanks to Prism.js for the syntax highlighting! I feel like it makes this all much easier to read.

Note, 18 July 2017
I’m no longer using Keystone JS on any web applications. In fact, I highly recommend checking out Express JS, GraphQL, React & MongoDB. It’s much simpler to build your own stateless applications. It’s also a far kinder experience on users and your servers (less page-loads).

 
13
Kudos
 
13
Kudos

Now read this

Using Web Workers to run JavaScript in parallel

JavaScript, in the browser, runs in a single thread. This is fine, and works fairly well for most websites. However, when running large, complex tasks or long scripts, it makes the webpage unresponsive. The best way to speed up these... Continue →