如何在与Jest的捕获语句中重新遇到错误
我有一个返回承诺的函数,但是我想测试它的捕获量定义,然后测试它会重新犯错。
这是一个非常人为的例子,但这是显示问题的最清晰方法。在我的实际代码中,我调用了一个被模拟失败的函数(与此示例中的手动拒绝),并且我在catch
语句中还有其他登录,该语句解释了重新启动错误。
const foo = () => {
return new Promise((resolve, reject) => {
reject(new Error('reject')); // manually rejecting to mimic actual code...
}).catch(error => {
// do some additional logging...
throw error;
});
};
it('should catch and re-throw error', () => {
// Received function did not throw
// and
// Unhandled promise rejection
expect(() => foo()).toThrow();
// Test passes, even when `throw error` is commented out with false positive
expect(foo()).rejects.toThrow();
});
我可以成功检查记录功能是否被调用,但无法弄清楚如何确保在此之后重新遇到错误。
工作更新:)
感谢 @skyboyer & @bergi 让我对问题有所不同,并将我暴露于
下面的一些更好的点是显示记录功能的更新代码,也是我解决的更新测试在。
导致此问题的问题无法
- 测试
记录
,由于重新遇到的错误 - 无法测试重新
捕获错误的错误值的错误使我可以做到这两个。
我本来要留在recupts.toequal
测试中,但是现在似乎多余了...
对任何反馈感兴趣!再次感谢!
// myModule.js
export const logging = () => {};
export const bar = () => new Promise(resolve => {});
export const foo = () => {
return bar().catch(error => {
logging();
throw error;
});
};
describe('myModule', () => {
let fooReturn;
beforeEach(() => {
jest.clearAllMocks();
jest.spyOn(myModule, 'bar').mockImplementation(() => {
return Promise.reject({ error: 'bar error' });
});
jest.spyOn(myModule, 'logging').mockImplementation(() => {});
fooReturn = myModule.foo();
});
it('should catch and re-throw error', () => {
expect.assertions(1);
fooReturn.catch(result => expect(result).toEqual({ error: 'bar error' }));
// removed since the above test covers that the promise was rejected
// return fooReturn.rejects.toEqual(expect.anything());
});
it('should call the loggin method', async () => {
expect.assertions(1);
// prevents UnhandledPromiseRejectionWarning
fooReturn.catch(() => {});
expect(myModule.logging).toBeCalled();
});
});
I have a function that returns a promise, but I want to test that it has a catch defined, and then additionally test that it re-throws the error.
This is a very contrived example but it was the clearest way to show the issue. In my actual code, I am calling a function that is mocked to fail (vs the manually rejecting in this example), and I have additional logging in the catch
statement, which explains the re-throwing of the error.
const foo = () => {
return new Promise((resolve, reject) => {
reject(new Error('reject')); // manually rejecting to mimic actual code...
}).catch(error => {
// do some additional logging...
throw error;
});
};
it('should catch and re-throw error', () => {
// Received function did not throw
// and
// Unhandled promise rejection
expect(() => foo()).toThrow();
// Test passes, even when `throw error` is commented out with false positive
expect(foo()).rejects.toThrow();
});
I can successfully check that the logging function is called, but can't figure out how to ensure the error is re-thrown after.
WORKING UPDATE :)
thanks to @skyboyer & @Bergi for getting me to think about the issue a bit differently, and exposing me to some of the finer points of jest
Below is both the updated code to show the logging function, and the updated tests i settled on.
The issues that led to this were
- unable to test
logging
was called due to the error being re-thrown - unable to test the value of the error being re-thrown
Catching the rejected promise allowed me to do both.
I was going to leave in the rejects.toEqual
test, but it seems redundant now...
interested in any feedback! and thanks again!
// myModule.js
export const logging = () => {};
export const bar = () => new Promise(resolve => {});
export const foo = () => {
return bar().catch(error => {
logging();
throw error;
});
};
describe('myModule', () => {
let fooReturn;
beforeEach(() => {
jest.clearAllMocks();
jest.spyOn(myModule, 'bar').mockImplementation(() => {
return Promise.reject({ error: 'bar error' });
});
jest.spyOn(myModule, 'logging').mockImplementation(() => {});
fooReturn = myModule.foo();
});
it('should catch and re-throw error', () => {
expect.assertions(1);
fooReturn.catch(result => expect(result).toEqual({ error: 'bar error' }));
// removed since the above test covers that the promise was rejected
// return fooReturn.rejects.toEqual(expect.anything());
});
it('should call the loggin method', async () => {
expect.assertions(1);
// prevents UnhandledPromiseRejectionWarning
fooReturn.catch(() => {});
expect(myModule.logging).toBeCalled();
});
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您错过了
返程
。https://jestjs.io/docs/asynchronous#resolves--rejects
您的测试应该是
你/Bergi 注意到
async/await
它可能看起来更简洁:但如果我们错过在
expect
之前添加await
,我们将遇到与版本中完全相同的问题1 没有返回
。所以要小心。You missed
return
.https://jestjs.io/docs/asynchronous#resolves--rejects
Your test should be
As u/Bergi noticed with
async/await
it may look more laconic:but if we miss to add
await
before ourexpect
we will have exact the same issue as in version 1 withoutreturn
. So beware.