Search code examples
typescriptnamespacessinonstub

Typescript: how to stub function from imported namespace


I have the following files

// definition file
export namespace Foo {
  export function foo() {
    bar();
  }
  export function bar() {
    throw 'not implemented yet'
  }
}

// test file
import { Foo } from 'fooFile'
describe('', () => {
  it('', () => {
    const sandbox = sinon.createSandbox();
    sandbox.stub(Foo, 'bar');
    Foo.foo(); // expected not to throw since I stubbed bar 
  });
});

and I don't know why it still throws. so far I've been able to stub functions imported from file with no namespace (import * as Foo from), methods and static methods from class, but I can't find the syntax for this stub.


Solution

  • Variable bar inside function foo() actually refers to local scope variable bar, but is undefined and then use global variable, which is defined. (Reference)

    AFAIK, You can not create stub from variable inside function.

    How to make sure that you call function bar() inside Foo namespace? Use this.bar() or Foo.bar(). Then now, your stub to method bar from namespace Foo can work in your test file (you have created stub correctly).

    For example, file foo.ts

    export namespace Foo {
      export function foo() {
        this.bar(); // Or use: Foo.bar().
      }
      export function bar() {
        throw 'not implemented yet'
      }
    }
    

    test file: stackoverflow.test.ts

    import sinon from 'sinon';
    import { expect } from 'chai';
    
    import { Foo } from './foo';
    
    describe('', function () {
      it('', function () {
        const stubFooBar = sinon.stub(Foo, 'bar');
    
        Foo.foo();
    
        expect(stubFooBar.calledOnce).to.equal(true);
        stubFooBar.restore();
      });
    });
    
    

    When I run it using mocha.

    $ npx ts-mocha stackoverflow.test.ts --exit
    
    
    
        ✓ 
    
    
      1 passing (6ms)
    
    $
    

    Hope this helps.