sinon stub 一个在 then 调用 promise 时执行的方法

sinon stub a method that was executed in then call of promise

describe("/test" , ()=> {

    // separate class 2
    class2 = {

        // function that i wanna stub
    hi: function () {
        return "hi";
    }
    }

// separate class 1
    class1 = {

        // function that i have stubbed and tested
         method1: function() {
           return new Promise((resolve, reject) => {
               resolve(num);

            })
        }

    }

    // method that i will execute
    var parent= function (){

        class1.method1().then(()=>{

            class2.hi();

        })

    }

    // the test
    it("should stub hi method",()=>{


        var hiTest = sinon.stub(class2, 'hi').resolves(5);
        var method1Test = sinon.stub(class1 , 'method1').resolves(5);

     // this start the execution of the promise with then call
        parent();

        // this works fine and test pass
        expect(method1Test.calledOnce.should.be.true);

        // this doesn't work although i executed the function
        expect(hiTest.calledOnce.should.be.true);

    })

})

我想做的是正确测试 hi 方法 .. 因为当我测试该方法是否执行一次时

尽管我在 promise 的 then 调用中执行了它,但它并没有显示它,并且它使 calledOnce 测试失败

这里的问题是您正在测试代码,就好像它是同步的,而实际上它不是(因为您正在使用 Promise)。


为了能够正确测试它,我们需要能够连接到以 parent 调用 class1.method1.

开始的承诺链

我们可以通过返回调用 class1.method1 returns 的承诺来做到这一点。

就测试本身而言,我们需要确保 Mocha 在等待承诺时不会结束测试,因此我们使用 done 回调参数告诉 Mocha 当我们认为测试完成时。


describe("/test", ()=> {
  class2 = {
    hi: function () {
      return "hi";
    }
  }

  class1 = {
    method1: function() {
      return new Promise((resolve, reject) => {
        resolve(num);
      })
    }
  }

  var parent = function (){
    return class1.method1().then(()=>{
      class2.hi();
    })
  }

  it("should stub hi method", (done)=> {
    var hiTest = sinon.stub(class2, 'hi').returns(5);
    var method1Test = sinon.stub(class1 , 'method1').resolves(5);

    parent().then(() => {
      expect(method1Test.calledOnce.should.be.true);
      expect(hiTest.calledOnce.should.be.true);
      done();
    });
  })
})