我将尝试用最少的复制代码来描述问题。
所以我有一个具有这种依赖性的函数:
import "./styles.css";
function thatRecivesInjectedDependency(aDependency) {
aDependency
.doSomethingAsync()
.then((result) => {
console.log("it happened");
})
.catch((error) => {
throw error;
});
}
export default thatRecivesInjectedDependency;
我想用像这样的双重测试来测试它:
import sut from ".";
test("should throw an error if the the assets load went wrong", async () => {
const fakeDependency = {
doSomethingAsync: jest
.fn()
.mockImplementation(() => Promise.reject(new Error("ERROR!")))
};
sut(fakeDependency);
await expect(fakeDependency.doSomethingAsync).rejects.toThrowError(
new Error("ERROR!")
);
});
由于某种原因,这是我发现可以进行测试的唯一方法,它不会给我带来假阳性结果,您可以通过更改mockImplementation
或{{1}中的错误文本来进行检查},它将失败,但仍然显示:
toThrowError
任何线索,它正在发生什么,如何解决?出什么事了吗?
答案 0 :(得分:0)
这是无人操作:
.catch((error) => {
throw error;
});
catch
可以被开发人员视为已处理的错误,但此错误只是将其抛出。如果意图是允许调用者处理错误,则可以将其省略。如果要抑制错误,可以将其更改为catch(() => {})
,但这可能会导致其他错误,因为调用者无法确定是否有错误,但这很重要。
thatRecivesInjectedDependency
不返回承诺,并且存在松散的承诺链。呼叫者无法链接它并等待thatRecivesInjectedDependency
完成。 catch
不能真正处理错误,因此无法在调用方中处理错误。
应该是:
return aDependency
.doSomethingAsync()
.then((result) => {
console.log("it happened");
});
测试不会链接结果,这将导致未处理的拒绝。相反,它会进行自我测试,因为它断言了模拟函数拒绝了。这是众所周知的,因为这正是上面几行写的。
可以通过断言console.log
来增加覆盖范围。
应该是:
jest.spyOn(console, 'log');
await expect(sut(fakeDependency)).rejects.toThrowError("ERROR!");
expect(console.log).not.toBeCalled();
请注意,toThrowError(new Error("ERROR!"))
过多,因为它只检查错误构造函数或消息,但不能同时检查两者。