How do I stub non object function using sinon
Asked Answered
B

3

8

I have a non object function

on getConfig.js

export default function () {
 /** do something **/
  return {
    appConfig: { status: true } 
    }
}

and under my main file

import getConfig from './getConfig';

export default function() {
 const { appConfig } = getConfig();
 
 if(appConfig.status) {
   console.log("do the right thing");
   else {
   console.log("do other things")
   }
  }
 }

How do I mock the getConfig function using sinon stub or mock methods? or is there any better way to set appConfig.status property to make true or false?

I would like to do the following but its not working

import getConfig from './getConfig';
import main from './main';

test('should status to be true', () => {
  
  sinon.stub(getConfig).callsFake(sinon.fake.returns({status:true});
  expect(main()).toBe('to do the right thing')
}
Boustrophedon answered 6/11, 2019 at 4:24 Comment(0)
M
0

Here's how you do this in Sinon:

import sinon from 'sinon';

import * as getConfigImport from './getConfig'; // This import syntax matters
import main from './main';

it(`passes`, () => {
  const consoleLogSpy = sinon.spy(console, 'log');
  const getConfigDefaultFunction = sinon
    .stub(getConfigImport, 'default')
    .returns({
      appConfig: { status: true },
    });

    main();

    expect(consoleLogSpy.calledWith('do the right thing')).toBeTrue();
    expect(consoleLogSpy.calledOnce).toBeTrue();
});

This test passes and you can modify various aspects of it to prove to yourself it's testing what it's actually supposed to.

Note you'll want to call sinon.restore() after each test. You can learn about it here.

I'm using the Jasmine test framework, but it shouldn't matter. I'm also writing this in TypeScript, but I don't think that should matter either.

Mab answered 6/5 at 0:48 Comment(0)
U
-1

The getConfig function just returns an object so you should just check the returned value (the object.) You don't need sinon at all. What you need to do is asserting the returned value. You can use mocha test runner for running the tests and an assertion toolking like node's internal assert module for assertion.

"is there any better way to set appConfig.status property to make true or false?" How about adding an argument to the function?

// using default values for properties
export default function(status = true) {
  // no need for additional `appConfig` property
  return { status };
}

Testing (see the mocha manual for setting up the environment):

import getConfig from './getConfig';
import assert from 'assert';

describe('getConfig', function() {
    it('should return { status: true } by default', function() {
      const ret = getConfig();
      assert.deepEqual(ret, { status: true });
    });
    it('should return { status: false } by passing `false`', function() {
      const ret = getConfig(false);
      assert.deepEqual(ret, { status: false });
    });
});
Underlay answered 6/11, 2019 at 5:2 Comment(2)
Thanks for the answer I have posted the skeleton of my function on the top, in general the status value get calculated in the getConfig file and based on some logic it returns status true or false. and sometimes the appConfig would not have status valueBoustrophedon
You are welcome. It's just a basic example, You can use the same logic for testing your main function, return values instead of using the console.log function and assert the returned values. You can also use the chai assertion library.Underlay
B
-3

Ok I found another alternate solution using just JEST

jest.mock('./getConfig', () => (
 jest.fn()
 .mockReturnValueOnce({ appConfig: { status: true }})
 .mockReturnValueOnce({ appConfig: { status: false }})
))

//The getConfig get replaced with the above mock function

So the solution looks like

import main from './main';

jest.mock('./getConfig', () => (
 jest.fn()
 .mockReturnValueOnce({ appConfig: { status: true }})
 .mockReturnValueOnce({ appConfig: { status: false }})
))


test('should status to be true', () => {
  expect(main()).toBe('to do the right thing')
  expect(main()).toBe('to do the other things')
}
Boustrophedon answered 6/11, 2019 at 5:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.