npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

test-controller

v4.0.0

Published

Testing module for the controllers. Extends req and res from dupertest

Downloads

30

Readme

Test controller

js-semistandard-style

Testing module for the controllers. Extends req and res from dupertest, perform authentication, add data on the fly and perform more operations to test the controllers.

Getting started

If you are installing a testing suite to mock your request and response you probably know what you're doing. But anyway, for the beginners. Install it in your repo using npm:

npm install test-controller --save

Require it within your code (within the test code):

// /tests/controller/index.js

// Some testing modules (not needed, but they are nice to have)
var chai = require('chai');
var should = chai.should();
var expect = chai.expect;

// The actual testing controller module
var test = require('test-controller');

// ... your tests

Usage

A simple example of how to mock a request.

test(controller.show).get({}, function(type, file, locals){
  expect(type).to.equal('render');
  expect(file).to.equal('home/index');
  expect(locals.list).to.be.an.array;
  done();
});

These are the methods for the variable test:

| method | description | |----------------------------|-----------------------------------------------------------------| | .get(data [, callback]) | perform a get request to the controller | | .post(data [, callback]) | perform a post request to the controller | | .auth(mockuser) | add the property user to the req as the object passed | | .params(data) | add the data to the get request, overwriting when needed | | .body(data) | add the data to the post request, overwriting when needed | | .end(callback) | send the request (rarely needed) |

And those are the properties (most are appended, see below):

| properties | description | |-------------------|----------------------------------------------| | test | the function to test | | request | the request object and properties |

With pray

Pray is a library made to be combined with test-controller to simplify testing. For the same example as above:

test(controller.show).get({}, pray(
  'render',
  'home/index',
  locals => expect(locals.list).to.be.an.array,
  done
));

So we will include examples both vanilla and with pray from now on.

Callback

The callback that is passed to .get(data, callback), .post(data, callback) and .end(callback), receives 2+ arguments in the following way:

  1. Type of response or 'error' if next() was called with an error
  2. First argument of the response if any
  3. Second argument of the response if any
  4. Third ...
  5. ...

Error handling for the callback

Since the version 3.x this has changed, so please read the new documentation

For example, for the following controller:

// Controller (example)
module.exports.show = function(req, res, next){
  if (!req.params.id) next(new Error('No id provided'));
  res.render('show', { title: 'Hello world', id: req.params.id });
};

When testing it, the callback will look like this:

test(controller.show).get({ id: 1 }, function(type, jade, locals){
  type = 'render';
  jade = 'show';
  locals = { title: 'Hello world', id: 1 };
});

On the other hand (and that's why this library was born), if you don't pass the id you get the following:

test(controller.show).get({}, function(type, message){
  type = 'error';
  jade = '[Error] No id provided';   // Error object and it's stacktrace
});

Response type for the callback

You can also test the type of response given. For this controller:

// Controller (example)
module.exports.show = function(req, res, next){
  if (!req.params.id || !req.params.id.match(/[0-9]+/)) {
    res.redirect('/');
  }

  res.render('show', { title: 'Hello world', id: req.params.id });
};

Test this way that depending on the get arguments :

it('If no id given, go back to home', function(done){
  test(controller.show).get({}, function(type, url){
    expect(type).to.equal('redirect');
    expect(url).to.equal('/');
    done();
  });
});

it('Show the element if an id is given', function(done){
  test(controller.show).get({ id: 1 }, function(type, file, locals){
    expect(type).to.equal('render');
    expect(file).to.equal('index/show');
    expect(locals.id).to.equal(1);
    done();
  });
});

And with pray:

it('If no id given, go back to home', function(done){
  test(controller.show).get({}, pray('redirect', '/', done));
});

it('Show the element if an id is given', function(done){
  var locals = locals => expect(locals.id).to.equal(1);
  test(controller.show).get({ id: 1 }, pray('render', 'index/show', locals, done));
});

Methods

There are many chainable methods that can be used and all of them can be chained.

constructor(fn)

This method expects one function that will be tested against the data given later on. This function accepts a req, res and (optionally) next parameters, which will be mocked by the module. Example:

// Load the module
var test = require('test-controller');

// Include the controller to be tested (it has several methods)
var controller = require('../controller/home');

// Test the method `index` from the controller, performing a get request to it
test(controller.index).get({}, function (type, data) { });

.get(data [, callback])

Perform a get request to the specified controller

// Test the method `index` from the controller, performing a get request to it
test(controller.index).get({}, function(type, data){ });

// Test the method `show` from the controller for a single id
test(controller.show).get({ id: 24 }, function(type, data){ });

.post(data [, callback])

Perform a post request to the specified controller. Some examples:

// When you need to add something but you don't
it('does not allow you to post nothing', function(done){
  test(controller.add).post({}, function(type){
    expect(type).not.to.equal('error');
  });
});

// Then you do submit it, good job!
it('allows you to post real data as a non-authenticated user', function(done){
  test(controller.add).post({ id: 24, value: 87 }, function(type, data){
    expect(type).to.equal('redirect');
    done();
  });
});

.put(data [, callback])

Works in the same way as .post(data [, callback])

.delete(data [, callback])

Works in the same way as .get(data [, callback])

.auth(mockuser)

This method created the property req.user and fills it with the data passed or truish (empty object) if no data is passed. This is normally expected to be done by the authentication system that you have, so it's a way to perform authenticated calls to your methods. It function returns this so you can chain it with any method you want. Usage:

var mockuser = { name: 'Tim', role: 'admin' };

it ('loads the admin page for an admin', function(done){
  test(adminController.index).auth(mockuser).get({}, function(type){
    console.log("This was an authenticated call");
    expect(type).to.equal('render');
    done();
  });