How to Test PUT method using supertest and jasmine-node

Jibolash picture Jibolash · May 7, 2015 · Viewed 7.9k times · Source

I am building an API with expressjs and my routes look like this

module.exports = function(app){
var book = require('../controllers/book.controller');

app.get('/api/books', book.getBooks); //get all books
app.post('/api/books', book.addBook); //add a book
app.put('/api/book/:book_id', book.updateBook); //update a book entry
app.delete('/api/book/:book_id', book.deleteBook); //delete a book
}

The callback functions are defined as follows

var Book = require('../models/book.model');

module.exports = {
  addBook: function(req, res){
    Book.create(req.body, function(err, book){
      if(err){
        return res.json(400, err);
      }
      res.status(201).json(book);
    });
  },

  getBooks: function(req, res){
    Book.find({}).exec(function(err, books){
      if(err){
        return res.json(400, err);
      }
      res.status(201).json(books);
    });
  },

  getOneBook: function(req, res){
    Book.findById({_id: req.params.book_id}, function(err, book){
      if(error){
        return res.json(400, err)
      }
      res.status(201).json(book);
    })
  },

  updateBook: function(req, res){
    Book.update({_id: req.params.book_id}, req.body, function(err, book){
      if(err){
        return res.json(400, err);
      }
      res.status(201).json(book);
    });
  },

  deleteBook: function(req, res){
    Book.remove({_id: req.params.book_id}, function(err, book){
      if(err){
        return res.json(400, err);
      }
      res.status(200).json(book);
    })
  }
};

I am testing the routes with jasmine-node and supertest and this is what I have done so far

var app = require('../app.js');
var request = require('supertest')(app);

describe('Test for book route', function(){

  it('Test GET method for /api/books', function(done){
    request
    .get('/api/books')
    .expect(201)
    .expect('Content-Type', 'application/json; charset=utf-8')
    .end(function(err, res){
      if(err){
        return done(err);
      }
      done();
    });
  });

  it('Test POST method for /api/books', function(done){
    var book = {title: 'Ake', author: 'Wole Soyinka', blurb: 'An autobiography'};
    request
      .post('api/books')
      .send(book)
      .expect(200)
      done();
  });
//THIS IS WHERE THE ISSUE IS
  it('Test PUT method for /api/book/:book_id', function(done){
    var bookEdit = {title: 'Ake', author: 'Wole Soyinka', blurb: 'An autobiography by the only Nigerian Nobel Laureate'};
    request
      .put('api/book/:book_id')
      .send(bookEdit)
      .expect(200)
      .done();
  });

});

What is the best way to get the book_id variable so I can edit the entry I created with the PUT test?

Answer

Boštjan Pišler picture Boštjan Pišler · Aug 13, 2015

You need to store the book's id to the variable you use to create the new book and later pass it as the id of the book you are trying to update.

That means you will need to put the book variable outside of the it function so it's accessible to the other it functions. Also the post it function needs to access the response to obtain the returned book's content.

This is the part of the test code that needed to be updated:

...

var book = {title: 'Ake', author: 'Wole Soyinka', blurb: 'An autobiography'};

...

it('Test POST method for /api/books', function(done){
  var book = {title: 'Ake', author: 'Wole Soyinka', blurb: 'An autobiography'};
  request
    .post('api/books')
    .send(book)
    .expect(200)
    .end(function(err, res){
      if(err){
        return done(err);
      }
      book = res.body;
      done();
    });
});

it('Test PUT method for /api/book/:book_id', function(done){
  var bookEdit = {title: 'Ake', author: 'Wole Soyinka', blurb: 'An autobiography by the only Nigerian Nobel Laureate'};
  request
    .put('api/book/' + book._id)
    .send(bookEdit)
    .expect(200)
    .done();
});