6

I'm writing an app in node.js that includes some connect style endpoint handlers ( function(req,resp) ) and would like to write some unit tests against them without requiring the full app to be running.

I know I can "simply" push whatever fixture I manually write into it, but I was wondering if there is any library out there to help me generate these fixtures faster.

EDIT: to further explain what i want, I would like to in my unit test execute my handler only (not my app) and for that, i'd need a fake req and res. Those are the 2 objects I'd like to mock.

I'm currently using mocha as the test runner and the core assert module.

Miguel Coquet
  • 300
  • 2
  • 10

3 Answers3

2

If you defined your routes in a way where you pass app to a function then you could use supertest to test a route.

Test

var app = require('./real-or-fixture-app'); //depends on your setup

require('routeToTest')(app);

var request = require("supertest");

describe("Test", function(){
    it("should test a route", function(done){
        request(app)
            .post("/route")
            .send({data:1})
            .expect(200, done);
    });
});

Route definition

module.exports = function(app){
    app.get("/route", ....
};

I am not quite sure that this is really what you are looking for, but it is a way to test your routes separately.

topek
  • 18,609
  • 3
  • 35
  • 43
  • This is useful, albeit not exactly what i'm looking for. I'll edit the question to try and explain better what i'm looking for. Thanks for replying though :) In the meantime i went with something very similar. I might refactor what i did to use supertest as it looks cleaner. – Miguel Coquet Jan 23 '13 at 09:35
2

I know this question is old, but a great way to do this now is with Supertest https://github.com/visionmedia/supertest

If you've ever used the Django test Client library, it works a lot like that. It simulates running your views/routes so that you get a test scenario more like if an actual browser were hitting your view. That means that req and res are mocked out but behave in an expected way. It's way faster than Selenium (or, for example, protractor, which uses Webdriver under the covers).

As you probably know, it's a great idea to move as much of your logic out of your routes so that it can be unit tested separately. I don't really consider using Supertest as unit testing, since you're invariably testing more than a single unit of code.

newz2000
  • 2,602
  • 1
  • 23
  • 31
  • Yes. I already had my "business logic" inside its own module, but I was looking for a way to test that the endpoints worked. In the end I realised that what I was really looking for was more integration than unit, so Superttest for the "integration" level and unit for the module worked out just fine :) – Miguel Coquet Jun 18 '14 at 09:11
1

You might be interested in a small package I put together that makes creating mock request/responses a bit easier using Sinon.

In essence it just creates an object that mimics the standard req/res from express and replaces the method with spys that you can inspect.

From the README:

Your test:

import route from '../src/foo'
import { mockReq, mockRes } from 'sinon-express-mock'

describe('my route', () => {
  it('should foo the bar', () => {

    const body = {
      body: {
        foo: 'bar',
      },
    }
    const req = mockReq(body)
    const res = mockRes()

    route(req, res)

    expect(res.json).to.be.calledWith({ foo: body.foo.bar })
  })
})

Contents of src/foo.js:

export default (req, res) => {
  res.json({ foo: req.body.bar })
}

https://github.com/danawoodman/sinon-express-mock

Dana Woodman
  • 4,148
  • 1
  • 38
  • 35