Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force error branch in jasmine-node test

I'm testing the controller logic behind API endpoints in my node server with jasmine-node. Here is what this controller logic typically looks like:

var getSummary = function(req, res) {
  var playerId = req.params.playerId;

  db.players.getAccountSummary(playerId, function(err, summary) {
    if (err) {
      logger.warn('Error while retrieving summary for player %d.', playerId, err);
      return res.status(500).json({
        message: err.message || 'Error while retrieving summary.',
        success: false
      });
    } else {
      res.json({success: true, summary: summary});
    }
  });
};

Below is how I successfully test the else block:

describe('GET /api/players/:playerId/summary', function() {
  it('should return an object summarizing the player account',   function(done) {
    request
      .get('/api/players/' + playerId + '/summary')
      .set('Content-Type', 'application/json')
      .set('cookie', cookie)
      .expect(200)
      .expect('Content-Type', /json/)
      .end(function(err, res) {
        expect(err).toBeNull(err ? err.message : null);
        expect(res.body.success).toBe(true);
        expect(res.body.summary).toBeDefined();
        done();
      });
  });
});

This works nicely, but leaves me with poor branch coverage as the if block is never tested. My question is, how do I force the error block to run in a test? Can I mock a response which is set to return an error so that I can test the correct warning is logged and correct data is passed back?

like image 314
MattDionis Avatar asked Oct 01 '16 17:10

MattDionis


People also ask

How do you force a test to fail in Jasmine?

Jasmine provides a global method fail() , which can be used inside spec blocks it() and also allows to use custom error message: it('should finish successfully', function (done) { MyService. getNumber() . success(function (number) { expect(number).

How do you catch error in Jasmine?

var throwMeAnError = function() { //throw new Error(); }; describe("Different Methods of Expect Block",function() { var exp = 25; it("Hey this will throw an Error ", function() { expect(throwMeAnError). toThrow(); }); });

How to use Jasmine unit testing for nodejs applications?

In order to use Jasmine unit testing for Node.js applications, a series of steps need to be followed. In our example below, we are going to define a module which adds 2 numbers which need to be tested. We will then define a separate code file with the test code and then use jasmine to test the Add function accordingly.

How to install Jasmine in NodeJS?

You to need to install jasmine module to use the jasmine framework from within a Node application. To install the jasmine-node module, run the below command. npm install jasmine-node. Step 2) Initializing the project – By doing this, jasmine creates a spec directory and configuration json for you.

Is it possible to have nested describe block in Jasmine?

Good thing is, you can have nested describe blocks as well. In case of nested describe, before executing a spec, Jasmine walks down executing each beforeEach function in order, then executes the spec, and lastly walks up executing each afterEach function. Let’s understand it by an example.

Is it possible to test a JavaScript function with Jasmine?

Jasmine is very capable framework for testing javascript functions, but learning curve is little bit difficult. It will require a great amount of discipline in writing actual javascript code – before it could be tested with Jasmine effectively.


1 Answers

It depends on your tests. If you only want to unit test, spies are the way to go. You can just stub your db response. Be aware that in this case the database is not called though. It's just simulated.

const db = require('./yourDbModel');
spyOn(db.players, 'getAccountSummary').and.callFake(function(id, cb) {
  cb(new Error('database error');
});

request
  .get('/api/players/' + playerId + '/summary')
  .set('Content-Type', 'application/json')
  .set('cookie', cookie)
  .expect(500)
  // ...

If you want functional/integration tests, you need to call your request simply with wrong data, for example a players id that doesn't exist in your database.

request
  .get('/api/players/i_am_no_player/summary')
  .set('Content-Type', 'application/json')
  .set('cookie', cookie)
  .expect(500)
  // ...
like image 146
Johannes Merz Avatar answered Oct 12 '22 23:10

Johannes Merz