Search code examples
node.jsunit-testingexpresssails.jssupertest

Sails.js and Mocha: Using supertest to create a new model


I'm currently setting up testing infrastructure for my Sails app, and it was going smoothly until I tried testing API requests with supertest.

I'm trying to test some of my controller methods (that I implemented instead of using the default blueprint routes), but it seems like the API request isn't even going through. The reason I think this is because I can run npm test and this code will run fine, but if I change the POST path to /datamodel/create5, where create5() does NOT exist as a controller method, it still runs fine... In both cases, a DataModel model is NOT created. I've included some code below.

This is what my code looks like:

var request = require('supertest');
var assert = require('assert');
var async = require('async');
var stubs = require('../stubs.js');

describe('DataModel', function() {
  var testDataModel;
  var dataModelParams = stubs.dataModelStub(); // simply returns a JSON dictionary

  describe('#create()', function() {
    describe('data model import', function() {
      it('should import a new data model.', function (done) {
        var agent = request.agent(sails.hooks.http.app);

        agent
          .post('/datamodel/create')
          .send(dataModelParams)
          .expect(302)
          .end(function (err, res) {
            if (err) {
              throw new Error(err);
            }
            console.log(res.dataModel);

            DataModel.find().exec(function (err, dataModels) {
              console.log(dataModels); // should return an array of 1 model but returns empty array instead
              done();
            });
          });
      });
  });
});

Snippet of my controller code:

  create: function(req, res) {
    DataModel.create(req.params.all(), function dataModelCreated(err, dataModel) {
      if (err) {
        sails.log.debug(err);
      }

      FlashService.success(req, 'Successfully imported a new data model.');
      fs.ensureDirSync(path.join(sails.config.paths.DATASET_EXTRACT_PATH, dataModel.fileSafeName));
      fs.ensureDirSync(path.join(sails.config.paths.DATASET_DOWNLOAD_ROOT, 'non_pii', dataModel.fileSafeName));
      fs.ensureDirSync(path.join(sails.config.paths.DATASET_DOWNLOAD_ROOT, 'pii', dataModel.fileSafeName));
      fs.ensureDirSync(path.join(sails.config.paths.DATASET_ENCRYPT_PATH, dataModel.fileSafeName));
      return res.redirect('/admin/manage_data_models');
    });
  }

Note that the create function runs correctly in practice when my app is launched. Any suggestions as to why my test isn't working properly? I'm using sails-memory for the tests if that helps.


Solution

  • I figured it out. I needed to authenticate my agent first (by making a call to the login route) before any of these calls would make it through.

    Essentially:

    var agent = request.agent(sails.hooks.http.app);
    agent.post('YOUR_LOGIN_ROUTE').end(done);
    
    // do your tests