问题
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