3

Just checking that we're exporting an object is failing as follows:

import * as Foo from './foo';

describe('Foo', () => {
  test('should export an object', () => {
    expect(Foo).toBeInstanceOf(Object);
  });
});

getting this error:

expect(received).toBeInstanceOf(expected)

While I can workaround using typeof:

import * as Foo from './foo';

describe('Foo', () => {
  test('should export an object', () => {
-    expect(Foo).toBeInstanceOf(Object);
+    expect(typeof LivingAppsCoreReact).toEqual('object');
  });
});

I'd like to understand why Jest defines that Object constructor isn't... Object constructor.

Checked that the object is exporting the actual keys ✅


Env:

$» npm ls jest                                                            1 ↵
my-project@0.31.5
├── jest@29.3.1
└─┬ ts-jest@29.0.3
  └── jest@29.3.1 deduped
Manu Artero
  • 9,238
  • 6
  • 58
  • 73
  • Note that a *lot* of things are objects in JS. `null` is one in `typeof`, `[]` is one for both `typeof` and `instanceof`, etc. That means this test isn't asserting a lot. See: https://stackoverflow.com/a/8511350/3072442 – Leland Feb 26 '23 at 01:10

2 Answers2

1

This might be a bug on Jest/Node side, as the globals on Jest environment differ from Node's, see:

When you use a default export, the type of your exported element is Object, and then when you compare it to "Jest's Object type" that fails the test as they're in different contexts.

This is also related to behaviors like: https://stackoverflow.com/a/75524385/5078746


In your case, you can use destructuring in case you are using named exports (e.g export const Foo = {...}) which will lead Jest to evaluate your objects in the same context.

I mean move from

import * as Foo from './foo';

To

import { Foo } from './foo';

Or, you can check for object properties with .toMatchObject(object) instead of checking if the Object is an Object.

Fcmam5
  • 4,888
  • 1
  • 16
  • 33
0

Jest globals differ from Node globals

That's one of the longest arguments between Jest and Node. There is a difference between the Jest globals and the Node globals - you can find more information on this github's open issue Jest globals differ from Node globals.

In other words, the toBeInstanceOf function works for object instances of classes that you create. However, it won't work correctly for an instance of the global Array class. I would consider using the toBeInstanceOf function for asserting against your example above. Please have a look at the toBeInstanceOf docs and the example code below.

That's from the docs

describe('toMatchObject applied to arrays', () => {
  test('the number of elements must match exactly', () => {
    expect([{foo: 'bar'}, {baz: 1}]).toMatchObject([{foo: 'bar'}, {baz: 1}]);
  });

  test('.toMatchObject is called for each elements, so extra object properties are okay', () => {
    expect([{foo: 'bar'}, {baz: 1, extra: 'quux'}]).toMatchObject([
      {foo: 'bar'},
      {baz: 1},
    ]);
  });
});
Evan
  • 35
  • 4