简体   繁体   中英

How do I unit-test a function that calls other functions in the same file/class so I can't mock them?

I have got a function that calls some other functions, and I want to write unit tests for it now. The problem is, when checking if the functions get called correctly, they are of course also executed which does not work correctly in my testing environment, so mocha shows errors.
The function I'm testing could look like this for example:

topFunction(foo, bar){
  if(foo === bar){
    function1();
  } 
  // ...
  function2(foo);
}

function1 and function2 are in the same file/class under test as topFunction .

  1. If I want to test whether function1 and function2 get called correctly, how do I do that correctly?
    I know I could pass the functions to topFunction as arguments, or put them into another class that I then pass to the class that topFunction is in so I can mock function1 and function2 when testing.
  2. Is this kind of trouble testing functions an indicator of bad design, so I should change the code (maybe the way I suggested?) instead of finding a workaround?

Using sinon.js as the assertion library. Furthermore, You can read this issue . Here is the unit test solution:

index.js :

function function1() {}

function function2(arg) {}

class SomeClass {
  topFunction(foo, bar) {
    if (foo === bar) {
      exports.function1();
    }
    exports.function2(foo);
  }
}

exports.function1 = function1;
exports.function2 = function2;
exports.SomeClass = SomeClass;

index.test.js :

const sinon = require("sinon");
const mod = require("./");

describe("59877615", () => {
  afterEach(() => {
    sinon.restore();
  });
  it("should call function1 and function2", () => {
    const funtion1Stub = sinon.stub(mod, "function1");
    const funtion2Stub = sinon.stub(mod, "function2");
    const instance = new mod.SomeClass();
    instance.topFunction("a", "a");
    sinon.assert.calledOnce(funtion1Stub);
    sinon.assert.calledOnce(funtion2Stub);
  });

  it("should only call function2", () => {
    const funtion2Stub = sinon.stub(mod, "function2");
    const instance = new mod.SomeClass();
    instance.topFunction("a", "b");
    sinon.assert.calledOnce(funtion2Stub);
  });
});

Unit test results with coverage report:

 59877615
    ✓ should call function1 and function2
    ✓ should only call function2


  2 passing (10ms)

---------------|----------|----------|----------|----------|-------------------|
File           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
---------------|----------|----------|----------|----------|-------------------|
All files      |      100 |      100 |    71.43 |      100 |                   |
 index.js      |      100 |      100 |    33.33 |      100 |                   |
 index.test.js |      100 |      100 |      100 |      100 |                   |
---------------|----------|----------|----------|----------|-------------------|

Source code: https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/59877615

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM