问题
class TestObject {
constructor(value) {
if (value === null || value === undefined) {
throw new Error('Expect a value!');
}
}
}
describe('test the constructor', () => {
test('it works', () => {
expect(() => {
new TestObject();
}).toThrow();
});
test('not work', () => {
expect(new TestObject()).toThrow();
});
});
2 Test cases here, one works and the other not.
The failing message for the not work one is as the following:
● test the constructor › not work
Expect a value!
at new TestObject (tests/client/utils/aaa.test.js:4:11) at Object.<anonymous> (tests/client/utils/aaa.test.js:17:12) at Promise (<anonymous>) at <anonymous> at process._tickCallback (internal/process/next_tick.js:188:7)
Why do I need to wrap that call in a function call, we don't need to wrap when the function just return a plain value, or even a promise, we can use async/await to check that in expect() rather than create a function inside expect().
What happened here?
回答1:
Here
expect(new TestObject()).toThrow();
new TestObject() is evaluated first, then expect(...), then ...toThrow(), in accordance with operator precedence. When new TestObject() throws, anything else doesn't matter.
This is why toThrow expects a function that is supposed to throw:
expect(() => {
new TestObject();
}).toThrow();
This way it can be wrapped with try..catch internally when being called.
It works similarly in Jasmine toThrow and Chai to.throw assertions as well.
来源:https://stackoverflow.com/questions/46707357/why-jests-tothrow-wont-work-when-create-an-instance-of-a-es6-class-directly-in