Writing unit tests for method that uses jwt token in javascript

John Samuel picture John Samuel · Feb 19, 2018 · Viewed 10.2k times · Source

I have been trying to write unit test in javascript for the method which uses jwt token validation. So the results are fetched only if the token is valid.

I want to mock the jwt token and return results. Is there any way to do it ? I tried using ava test framework, mock require, sinon but I am unable to do it.

Any thoughts ?

Code:

I am trying to mock jwt.verify    

**unit test:**

const promiseFn = Promise.resolve({ success: 'Token is valid' });

mock('jsonwebtoken', {
        verify: function () {         
            return promiseFn;   
        }
});

const jwt = require('jsonwebtoken');

const data =  jwt.verify(testToken,'testSecret');

console.log(data)


**Error :**

ERROR
    {"name":"JsonWebTokenError","message":"invalid token"} 


So the issue here is that, its actually verifying the token but not invoking the mock.

Answer

Antonio Narkevich picture Antonio Narkevich · Feb 19, 2018

Modules are singletons in Node.js. So if you required 'jwt' in your test and then it's required down in your business logic it's going to be the same object.

So pretty much you can require 'jwt' module in your test and then mock the verify method.

Also, it's important not to forget to restore the mock after the test is done.

Here is a minimal working example of what you want to accomplish (using ava and sinon):

const test = require('ava');
const sinon = require('sinon');
const jwt = require('jsonwebtoken');

let stub;

test.before(t => {
    stub = sinon.stub(jwt, 'verify').callsFake(() => {
        return Promise.resolve({success: 'Token is valid'});
    });
})

test('should return success', async t => {
    const testToken = 'test';
    const testSecret = 'test secret';

    const result = await jwt.verify(testToken, testSecret);

    console.log(result);

    t.is(result.success, 'Token is valid');
});

test.after('cleanup', t => {
    stub.restore();
})