Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Jest's toThrow won't work when create an instance of a ES6 class directly in the constructor?

Tags:

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?

like image 384
Albert Gao Avatar asked Oct 12 '17 10:10

Albert Gao


People also ask

Is not a constructor typescript error?

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.

What is the difference between class and constructor in JavaScript?

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.

How do you mock a constructor in Jest?

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.

Why should we use ES6 classes?

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.


1 Answers

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.

like image 68
Estus Flask Avatar answered Oct 05 '22 01:10

Estus Flask