Sei*_*Day 3 unit-testing node.js promise jestjs
请记住,我对 Jest 还很陌生,而且我对 Node 的内部结构也不是很熟悉Promise。我知道async函数实际上是返回 a 的函数Promise,并且我在这种想法上取得了很大的成功。
我有一个正在尝试测试的功能。它具有在执行任何其他工作之前导入的依赖项。根据传递给 的输入foo,该依赖项可能会返回不同的内容,这可能会或可能不会影响 的结果foo。它是这样的:
// foo.js
const someOtherWork = require("../bar/baz");
module.exports = async function foo() {
const array = await someOtherWork();
... do other things ...
return someStuff;
}
Run Code Online (Sandbox Code Playgroud)
foo我导入一个函数来帮助完成正在尝试做的工作。
someOtherWork在我的测试中,我像这样监视该函数:
// foo.test.js
const someOtherWork = jest.requireActual("../bar/baz");
const mockSomeOtherWork = jest.fn().mockImplementation(someOtherWork);
jest.mock("../bar/baz", () => mockSomeOtherWork);
const foo = require("./foo.js");
// ...tests...
Run Code Online (Sandbox Code Playgroud)
这样,我就可以断言它mockSomeOtherWork是使用特定参数调用的,甚至它返回了正确的输出。当我的模拟依赖项(someOtherWork在本例中)返回一个Promise.
当我尝试断言已解析为Promise特定值而不调用测试代码中的模拟函数时,它总是通过测试:
expect(mockSomeOtherWork).toHaveReturnedWith(Promise.resolve([my, array, of, expected, values])); // succeeds correctly
expect(mockSomeOtherWork).toHaveReturnedWith(Promise.reject("lol nope"); // succeeds ERRONEOUSLY
Run Code Online (Sandbox Code Playgroud)
当我断言它返回Array或其他任何内容时,我已经成功地失败了测试,如下所示:
expect(mockSomeOtherWork).toHaveReturnedWith(Array); // fails correctly
expect(mockSomeOtherWork).toHaveReturnedWith([my, array, of, expected, values]); // fails correctly
Run Code Online (Sandbox Code Playgroud)
但任何形式都Promise 通过了测试,这意味着我不能从我的断言中假设任何内容!
我开始发现,对于 Jest 来说, aPromise是一个几乎不透明的对象,我必须await使用它或附加回调(通过then或catch)来弄清楚里面的内容。承诺是否不会记住它们已经解析的值,以便我稍后检查,而无需重新调用返回它的函数?我不想依赖于断言 的其他依赖项someOtherWork或 的返回值foo,因为这些选项假设很多foo可能随时发生变化。我已经有一个有效的间谍模拟东西了someOtherWork。我应该抓住返回Promise的mockSomeOtherWork.mock.results[0].value那个await吗?是否有一种“正确”的方法来断言async被测单元的依赖性结果?
这是我的解决方法:
// If all is well, this should be a Promise
const results = mockSomeOtherWork.mock.results[0].value;
// If that Promise resolves to the right stuff, gucci!
const expected = [my, array, of, expected, values];
await expect(results).resolves.toStrictEqual(expected); // passes correctly
// This should fail, because the promise resolved to `expected`
const notExpected = [something, else];
await expect(results).resolves.toStrictEqual(notExpected); // fails correctly
Run Code Online (Sandbox Code Playgroud)
我认为,假设它Promise是不透明的,我确实需要await它来断言它的价值。我相信这样做不会发生额外的调用或工作,并且我可以通过断言来证明这一点expect(mockSomeOtherWork).toHaveBeenCalledTimes(1)。由于此断言在我上述解决方法之前和之后的测试中均成功,因此该调用必须位于foo.
如果 Jest 有一组匹配器就好了toHaveResolvedWith,但这对于我今天的目的来说已经足够好了。
| 归档时间: |
|
| 查看次数: |
3277 次 |
| 最近记录: |