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?
The JavaScript exception "is not a constructor" occurs when there was an attempt to use an object or a variable as a constructor, but that object or variable is not a constructor.
A class is a user-defined blueprint or prototype from which we create objects. Moreover, it represents the set of properties or methods that are common to all objects of one type. Additionally, a constructor is a block of code that initializes the newly created object.
In order to mock a constructor function, the module factory must return a constructor function. In other words, the module factory must be a function that returns a function - a higher-order function (HOF). Since calls to jest. mock() are hoisted to the top of the file, Jest prevents access to out-of-scope variables.
ES6 classes are syntactic sugar for the prototypical class system we use today. They make your code more concise and self-documenting, which is reason enough to use them (in my opinion). will give you something like: var Foo = (function () { function Foo(bar) { this.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With