javascriptunit-testingtestingjasminejasmine-node

How to use Jasmine.js spy on a required function


I have this code (Node.js):

File: utils.js

// utils.js
const foo = () => {
    // ....
}

const bar = () => {
    // ....
}

module.exports = { foo, bar }

File: myModule.js

// myModule.js
const {
    foo,
    bar
} = require('./utils');

const bizz = () => {
    let fooResult = foo()
    return bar(fooResult)
}

module.exports = { bizz }

File: myModule.spec.js

// myModule.spec.js
const { bizz } = require('./myModule');
describe('myModule', () => {

    it('bizz should return bla bla bla', () => {
        let foo = jasmine.createSpy('foo').and.returnValue(true)
        let bar = jasmine.createSpy('bar').and.callFake((data) => {
            expect(date).toBeTrue();
            return 'fake-data'
        })

        expect(bizz()).toBe('fake-data')
    })
})

I'm trying to test bizz using spies on foo and bar functions but it's not working well.

Can anyone explain to me how to create spies on these functions with the purpose to test bizz??


Solution

  • Yes, it is possible. You just need to require utils to spyOn first, then require myModule. The following test will pass.

    const utils = require('./utils');
    
    // myModule.spec.js
    describe('myModule', () => {
      it('bizz should return bla bla bla', () => {
        const fooSpy = spyOn(utils, 'foo').and.returnValue(true);
        const barSpy = spyOn(utils, 'bar').and.callFake(data => {
          expect(data).toBeTrue();
          return 'fake-data';
        });
    
        const { bizz } = require('./myModule'); // Import myModule after you added the spyOn
    
        expect(bizz()).toBe('fake-data');
    
        expect(fooSpy).toHaveBeenCalled();
        expect(barSpy).toHaveBeenCalled();
      });
    });
    

    Hope it helps