Node.js testing RESTful API (vows.js?)
Asked Answered
D

3

8

I could really do with some advice on testing a RESTful api I created in node.js. There are a plethora of frameworks out there and I am at a loss. My testing knowledge isn't good enough generally which is why I am trying to write these tests. I've tried vows.js which seems nice but I couldn't work out how to incorporate the testing of my API, I need some sort of client. An example of a simple post to test a login system is all I need to get going.

Duplicature answered 19/8, 2011 at 20:47 Comment(0)
D
7

Update 6 months later

vows-is sucks. use mocha

Original

Updated with vow-is code

Here's the vows-is example from the vows-is examples folder.

// simple HTTP
// Run with node example/simple-http.js

var express = require("express");
    is = require("../src/vows-is.js");

is.config({
    "server": {
        "factory": function _factory(cb) {
            var app = express.createServer();

            app.get("/", function(req, res) {
                res.send("hello world");
            })

            app.listen(3000);

            cb(app);
        },
        "uri": "http://localhost:3000",
        "kill": function _kill(app) {
            app.close();
        }
    }
});

is.suite("http request test").batch()

    .context("a request to GET /")
        .topic.is.a.request("GET /")
        .vow.it.should.have.status(200)
        .vow.it.should.have
            .header("content-type", "text/html; charset=utf-8")
        .context("contains a body that")
            .topic.is.property('body')
            .vow.it.should.be.ok
            .vow.it.should.include.string("hello world")

.suite().run({
    reporter: is.reporter
}, function() {
    console.log("finished");
    is.end();
})

This uses vows-is.

Dombrowski answered 19/8, 2011 at 23:33 Comment(0)
S
4

http://blog.nodejitsu.com/rest-easy-test-any-api-in-nodejs is designed for this very purpose. It's a DSL that sits on top of Vows that streamlines the process of writing out tests using vows.

Basic test:

//
// Here we will configure our tests to use 
// http://localhost:8080 as the remote address
// and to always send 'Content-Type': 'application/json'
//
suite.use('localhost', 8000)
     .setHeader('Content-Type', 'application/json');
     //
     // A GET Request to /ping
     //   should respond with 200
     //   should respond with { pong: true }
     //
     .get('/ping')
       .expect(200, { pong: true })
     //
     // A POST Request to /ping
     //   should respond with 200
     //   should respond with { dynamic_data: true }
     //
     .post('/ping', { dynamic_data: true })
       .expect(200, { dynamic_data: true })
Stormi answered 31/8, 2011 at 17:4 Comment(0)
A
1

I have used vowsjs and request libraries.

I have found them to be the easiest as both libs are documented properly and seem to be actively developed and maintained. (I haven't found the docs for APIeasy to be sufficient.)

Here's an example test I am writing at the moment to test Couchapp's HTTP API:

var request = require ('request')
    , vows = require ('vows')
    , assert = require ('assert');

var BASE_URL = "http://local.todos.com:5984/todos/"
    , HEADERS = {
      'Content-Type': 'application/json'
    }
    , revisionReference;

vows.describe ('CouchApp Todos REST API')
  // --------------------------------------------
  // Testing PUTs
  // ============================================
  .addBatch ({
    "A PUT to /todos/test-host without data": {
      topic : function () {
        request ({
          uri: BASE_URL + "test-host",
          method: 'PUT',
          headers: HEADERS
        }, this.callback );
      } 
      , "should respond with 201" : function ( err, res, body ) {
        assert.equal ( res.statusCode, 201 );
      }
      , "should have an id 'test-host'" : function ( err, res, body ) {
        assert.equal ( JSON.parse( res.body )._id, 'test-host' );
      }
      , "response should contain empty todos []" : function ( err, res, body ) {
        assert.include ( JSON.parse( res.body ), 'todos' );
        assert.deepEqual ( JSON.parse( res.body ).todos, [] );
      }
    }
  })
  .addBatch ({
    "A PUT to /todos/test-host with one todo item (an object)" : {
        topic : function () {
          request ({
            uri: BASE_URL + "test-host"
            , body: JSON.stringify({
                "title" : "Testing Todo",
                "isDone" : false
              })
            , method : "PUT"
            , headers : HEADERS
          }, this.callback );
        }
        , "should respond with 201" : function ( err, res, body ) {
          assert.equal ( res.statusCode, 201 );
        }
        , "should have an id 'test-host'" : function ( err, res, body ) {
          assert.equal ( JSON.parse( res.body )._id, 'test-host' )
        }
        , "response should contain todos array with one item" : function ( err, res, body ) {
          assert.include ( JSON.parse( res.body ), 'todos' );
          assert.deepEqual ( 
            JSON.parse( res.body ).todos
            , [{
              "title" : "Testing Todo",
              "isDone" : false,
              "_id" : 0
            }] 
          );
        }
    }
  })
Awning answered 25/10, 2011 at 15:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.