Reputation: 21351
When testing a function that uses either the TextEncoder or the TextDecoder I get:
ReferenceError: TextEncoder is not defined
ReferenceError: TextDecoder is not defined
I am using jsdom, so why is this not working?
Upvotes: 73
Views: 64631
Reputation: 627
There is a package that fixes this for anyone having this issue.
npm install jest-fixed-jsdom --save-dev
yarn add jest-fixed-jsdom --dev
Then in your jest.config.js|ts
file you add this config below likely replacing jsdom
module.exports = {
testEnvironment: 'jest-fixed-jsdom',
}
There some more information about this here Request/Response/TextEncoder is not defined (Jest)
Upvotes: 0
Reputation: 21351
While it should be bundled with jsdom, it isn't with jsdom 16. Therefore you can polyfill like so:
import { TextEncoder, TextDecoder } from 'util';
Object.assign(global, { TextDecoder, TextEncoder });
You will have to add that to the test or to a setupFile like setup.jest.ts
.
Upvotes: 135
Reputation: 776
To add to @leonheess's answer in TypeScript:
Add to the top of your testfile (in which the error occurs, before the line that causes the error):
import { TextEncoder, TextDecoder } from 'util'
global.TextEncoder = TextEncoder
// @ts-expect-error
global.TextDecoder = TextDecoder
Even when trying nicely, e.g.
import { TextEncoder, TextDecoder } from 'util'
global.TextEncoder = TextEncoder
global.TextDecoder = { prototype: TextDecoder }
I got errors like
Type 'typeof TextDecoder' is missing the following properties from type 'TextDecoder': decode, encoding, fatal, ignoreBOMts(2739)
Or with
global.TextDecoder = {prototype: new TextDecoder("utf-8")}
I get
Type 'import("util").TextDecoder' is not assignable to type 'TextDecoder'.
Types of property 'decode' are incompatible.
Type '(input?: ArrayBuffer | ArrayBufferView | null | undefined, options?: { stream?: boolean | undefined; } | undefined) => string' is not assignable to type '(input?: BufferSource | undefined, options?: TextDecodeOptions | undefined) => string'.
Types of parameters 'input' and 'input' are incompatible.
Type 'BufferSource | undefined' is not assignable to type 'ArrayBuffer | ArrayBufferView | null | undefined'.
Type 'ArrayBufferView' is not assignable to type 'ArrayBuffer | ArrayBufferView | null | undefined'.
Type 'ArrayBufferView' is missing the following properties from type 'DataView': getFloat32, getFloat64, getInt8, getInt16, and 17 more.
So better to just assign and ignore the incompatibilities.
import { TextEncoder, TextDecoder } from 'util'
global.TextEncoder = TextEncoder
// @ts-expect-error
global.TextDecoder = TextDecoder
EDIT: I know this is ugly, but found no other way.
Upvotes: 5
Reputation: 3091
I received this error as well and am using the standard Next.js jest and react testing library test setup outlined in the docs here: https://nextjs.org/docs/testing#setting-up-jest-with-the-rust-compiler.
In particular, it uses the testEnvironment: 'jest-environment-jsdom'
test environment in jest.config.js
configuration file.
Unfortunately, importing jsdom in one of my backend api routes (Express routes) broke my tests, giving me the TextEncoder is not defined
error.
I was able to fix it by adding the following to the top of the file that housed the broken test:
/**
* @jest-environment node
*/
// my-broken-node-only-test.js
Read more about this technique via the jest docs.
Lastly, the following issue comment by Jest maintainer Simen helped clarify what was happening in my case: https://github.com/jsdom/jsdom/issues/2524#issuecomment-902027138
Upvotes: 39