如何使用 Sinon JS 测试异步函数?

下面是我想要实现的一个最小示例:fn3()如果异步函数已fn2()解析(调用时fn1),我想测试被调用的情况。但是我以某种方式未能使用sinon的存根语法做到这一点。我想知道我误解了什么。


// System Under Test


export function fn1() {

    fn2().then(() => {

        fn3();

    });

}


export async function fn2() {

    return new Promise((resolve, reject) => {

        // expensive work

        resolve();

    });

}


export function fn3() {

    console.log("fn3");

}


// Test


import * as Page from "xxx";


it("test async", () => {

    // stub this async to isolate the SUT

    sinon.stub(Page, "fn2").resolves();

    const stub = sinon.stub(Page, "fn3");


    Page.fn1();


    sinon.assert.calledOnce(stub);

});



/*


    AssertError: expected fn3 to be called once but was called 0 times


      276 |         Page.fn1();

      277 |

    > 278 |         sinon.assert.calledOnce(stub);

          |                      ^

      279 |     });

      280 | });


      at Object.fail (node_modules/sinon/lib/sinon/assert.js:107:21)

      at failAssertion (node_modules/sinon/lib/sinon/assert.js:66:16)

      at Object.calledOnce (node_modules/sinon/lib/sinon/assert.js:92:13)

      at Object.<anonymous> (src/test.test.tsx:278:22)

*/


月关宝盒
浏览 76回答 1
1回答

九州编程

正如@jonrsharpe 所建议的那样,根据 JavaScript 的“单线程、事件循环”性质,您sinon.assert.calledOnce(stub);将在解决(即调用)fn2内部承诺之前被调用。这里有一篇文章供参考:https ://dev.to/lydiahallie/javascript-visualized-promises-async-await-5gke 。Page.fn1.then(() => { fn3(); })您可以尝试将代码更改为:&nbsp; &nbsp; ...&nbsp; &nbsp; return Page.fn1().then(() => {&nbsp; &nbsp; &nbsp; sinon.assert.calledOnce(stub);&nbsp; &nbsp; });&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; ...要么it("test async", async () => {&nbsp; &nbsp; // stub this async to isolate the SUT&nbsp; &nbsp; sinon.stub(Page, "fn2").resolves();&nbsp; &nbsp; const stub = sinon.stub(Page, "fn3");&nbsp; &nbsp; await Page.fn1();&nbsp; &nbsp; sinon.assert.calledOnce(stub);});所以在解决sinon.assert.calledOnce(stub);后会被调用Page.fn1()。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript