node.js - 期望被测函数内部模拟的解析值
问题描述
请记住,我对 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;
}
我导入一个函数来帮助完成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...
有了这个,我就可以断言它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
当我断言它返回一个Array
或其他任何东西时,我已经成功地失败了测试,如下所示:
expect(mockSomeOtherWork).toHaveReturnedWith(Array); // fails correctly
expect(mockSomeOtherWork).toHaveReturnedWith([my, array, of, expected, values]); // fails correctly
但是任何一种都Promise
通过了测试,这意味着我不能从我的断言中做出任何假设!
我开始发现,对于 Jest 来说,aPromise
是一个主要是不透明的对象,我必须await
使用它或附加回调(通过then
或catch
)来弄清楚里面是什么。Promise 是否不记得它们已经解析的值供我稍后检查,而无需重新调用返回它的函数?我不想依赖断言 的其他依赖项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
我认为,假设Promise
是不透明的,我确实需要await
它来断言它的价值。我相信我这样做不会发生额外的调用或工作,我可以通过断言来证明这一点expect(mockSomeOtherWork).toHaveBeenCalledTimes(1)
。由于这个断言在我上面的解决方法之前和之后的测试中都成功了,所以一个调用必须在foo
.
如果 Jest 有一组toHaveResolvedWith
匹配器会很好,但这对于我今天的目的来说已经足够好了。
推荐阅读
- php - 简单的 PHP MySQL SELECT 查询抓取旧数据
- c - xMapWindow 之前的 glClear(防止未定义的图形缓冲区)
- node.js - socketio连接有什么问题?
- graph-theory - 祖先抽样与吉布斯抽样/蒙特卡洛方法
- android-constraintlayout - android constraintlayout,是否可以按百分比设置mmaxWidth
- firebase - 使用带有双变量的 Flutter 和带有数字字段类型混淆的 Firestore
- python - 使用 scrapy 抓取电子商务
- android - Android:如何使 TextView 中只有一个单词变为粗体
- python - 在 Python 中出现海龟错误。乌龟.乌龟
- reactjs - React Native - 全局存储不可序列化对象的位置