Search code examples
javascriptunit-testingsinon

using sinon stub to test a method on an object


I want to test a function inside an object. The code, lets call it someFile.js, is structured as below.

import someService from 'a-location';

const val = someService.getVal();

const AnObject = {
  someMethod() {
   if(val) //dosomething
  }
}

export default AnObject;

In the test file, I have code as below

import someService from 'a-location';
import AnObject from 'someFile';

describe("description", function(){
  it('more description', function() {
    sinon.stub(someService, 'getVal').returns('my-val');
    AnObject.someMethod();
})
})

I was hoping to receive 'my-val' when someService.getVal() is called in the someFile.js but it isn't working as expected. What am I doing wrong?


Solution

  • You should use import() to import the AnObject from someFile dynamically after stubbing.

    E.g.

    some-file.ts:

    import someService from './a-location';
    
    const val = someService.getVal();
    
    const AnObject = {
      someMethod() {
        console.log('val: ', val);
      },
    };
    
    export default AnObject;
    

    a-location.ts:

    const someService = {
      getVal() {
        return 'real val';
      },
    };
    
    export default someService;
    

    some-file.test.ts:

    import sinon from 'sinon';
    import someService from './a-location';
    
    describe('description', () => {
      it('more description', async () => {
        sinon.stub(someService, 'getVal').returns('my-val');
        const AnObject = (await import('./some-file')).default;
        AnObject.someMethod();
      });
    });
    

    Test result:

      description
    val:  my-val
        ✓ more description
    
    
      1 passing (8ms)
    

    As you can see, the val is my-val which is a stubbed value.