异步/等待模拟

Kap*_*ius 2 javascript async-await ecmascript-2017

我想知道是否可以在测试中使用async / await做类似的事情。

有了常规的Promise,我可以例如在单元测试中模拟这样的Promise。

class Foo {
    fn() {
        this.someService.someFn().then((data) => this.data = data);
    }
}

describe("something", function() {
    beforeEach(function() {
        this.instance = new Foo();

        // Can this part be mocked out with the same idea, when someService.someFn is async fn
        this.instance.someService = {
            someFn: function() {
                return {
                    then: function(cb) {
                        cb("fake data");
                    }
                }
            }
        }

        this.instance.fn();

    });

    it("a test", function() {
        expect(this.instance.data).toBe("fake data");
    });
});
Run Code Online (Sandbox Code Playgroud)

(如果我覆盖了诺言,则不必处理冲洗或类似的操作。)但是现在,当fn()将变为

class Foo {
    async fn() {
        try {
            this.data = await this.someService.somefn();
        } catch() {

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在beforeEach中所做的覆盖将不再起作用。所以我的问题是...我可以做一些像我用async / await代码样式覆盖的承诺那样的事情。

这里的想法是,我想模拟外部依赖项,我正在单元测试中使用的功能(例如“ someService”)可能是什么。在该特定的单元测试中,我希望someService.someFn可以正常工作,并且可以模拟出它的响应。其他测试检查“ someFn”的有效性。

Leo*_*tny 5

首先,您的旧模拟应该与async/ 完美配合await。不过,最好使用Promise.resolve而不是使用.thenmethod 返回对象:

someFn: () => Promise.resolve('fake data')
Run Code Online (Sandbox Code Playgroud)

但是,由于您已经在使用async/ await,因此您也可以在测试中利用它:

someFn: async () => 'fake data'
Run Code Online (Sandbox Code Playgroud)