What is the best way to reset the testing subject between test cases using Jest and TypeScript?

I'm currently utilizing typescript alongside jest for unit testing. My goal is to create a simple unit test, but it consistently fails no matter what I try. Below is the snippet of code in question:

// initialize.ts
let initialized = false;
let secretName: string;

export function init(name: string) {
    if (initialized) {
        throw new Error("Cannot re-initialize.");
    }

    secretName = name;

    initialized = true;
}

export function getSecret(): string {
    return secretName;
}
// initialize.test.ts
describe("init", () => {
    async function getTestSubject() {
        return await import("./initialize");
    }

    it("should properly set the secret name", async () => {
        const init = await getTestSubject();
        init.init("bruce wayne");
        expect(init.getSecret()).toEqual("bruce wayne");
    });

    it("should trigger an exception if initialized more than once", async () => {
        const init = await getTestSubject();

        const callInit = function() {
            init.init("bruce wayne");
        };
        callInit();
        expect(callInit).toThrowError("Cannot re-initialize.");
    });
});

The reason the second unit test fails is due to an exception being thrown. The first "callInit()" should be the initial invocation of 'init' within that specific unit test. However, due to the setup, it is considered as the second call when both tests are taken into account.

I initially attempted importing 'init' at the top globally like this:

import {init, getSecret} from "./init";

Do you have any suggestions on how to rectify this issue? I believe this is quite a fundamental test scenario, so either there's a major limitation with jest or I might be overlooking something obvious...

Appreciate your help!

Answer №1

To make this code work, I implemented a solution by utilizing jest.resetModules() within a beforeEach() function to reset the module namespaces before each test.

let initModule

beforeEach(() => {
  jest.resetModules()
  initModule = require('./init')
})

it('should correctly set the secret name', () => {
  initModule.init('bruce wayne')
  expect(initModule.getSecret()).toEqual('bruce wayne')
})

it('should raise an error if initialized more than once', () => {
  const callInit = () => initModule.init('bruce wayne')
  callInit()
  expect(callInit).toThrowError('Cannot re-initialize.')
})

It is crucial in this scenario to import the other module inline because using the standard ES6 import does not allow for resetting the module namespace. As shown in the example above, I opted for the straightforward require() method to achieve this.

For TypeScript users seeking to maintain strong typing for initModule, importing it with the standard ES6 import can still fetch the type information.

import * as InitModule from './init'

let initModule: typeof InitModule

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Transform the string property extracted from the API into a JSON object

When making a request to an API, the data returned to the front end is in the following format: { name: 'Fred', data: [{'name': '"10\\" x 45\\" Nice Shirts (2-pack)"', 'price' ...

typescript code may not display a preview image

I recently came across a helpful link on Stack Overflow for converting an image to a byte array in Angular using TypeScript Convert an Image to byte array in Angular (typescript) However, I encountered an issue where the src attribute is not binding to t ...

What is preventing this from being a function?

It appears that the authenticationProvider is missing for some reason. @autoinject() export class ProviderManager implements AuthenticationManager { constructor( private container: Container ){ } public authenticate( creds: Credentials ): Promis ...

Version 4.6.4 of TypeScript is flagging the code as invalid

How can I fix this Typescript problem? const userInformation: { email: string; id: string; _token: string; _tokenExpirationDate: string; } = JSON.parse(localStorage.getItem('userData')); https://i.sstatic.net/xMh9P.pn ...

The NullInjector has issued an error regarding the lack of a provider for the Decimal

I recently integrated lazy loading into my application. However, one of my services is in need of the DecimalPipe. The structure of my modules goes like this: service -> shared module -> App module To give you more context, I have already added "Co ...

Tips on sorting through an array using Angular 11 and data

I'm working on a subpage that contains a large amount of detailed data in the form of thousands of records. I want to filter this data based on the "id" from my route, which is also included in the dataset. However, I've run into some difficultie ...

Angular 2 validation issue not functioning as anticipated

Here is a validator function that I have: export const PasswordsEqualValidator = (): ValidatorFn => { return (group: FormGroup): Observable<{[key: string]: boolean}> => { const passwordCtrl: FormControl = <FormControl>group.contr ...

Place information from an input field into a specific row within a table

Utilizing Angular 4, I am developing a frontend application for a specific project. The interface features a table with three rows that need to be filled with data from an external source. https://i.stack.imgur.com/Dg576.png Upon clicking the "aggiungi p ...

The act of exporting an enum from a user-defined TypeScript path leads to the error message "Module not

I have set up a custom path as explained in this particular discussion. "baseUrl": ".", "paths": { "@library/*": [ "./src/myFolder/*" ], } Within this module, I am exporting an Enum. export enum EN ...

Tips for utilizing buttons with the antd framework in Visual Studio Code

When using the Button and Input components from antd in vscode, I encountered an error specifically with the Button component and I am curious to understand why it is happening. Interestingly, when I tried using the Input component, it did not show any er ...

What is the correct way to utilize the mapState function within a TypeScript environment while implementing Vuex?

In my Vue.js project integrated with Vuex, I am using Typescript syntax. While trying to use the mapState method as computed in my .ts file, I encountered a syntax error. Currently, I am following the suggested syntax for computed function in the documenta ...

Place a new button at the bottom of the react-bootstrap-typeahead dropdown menu for additional functionality

Currently, I have successfully implemented the React Bootstrap Typeahead with the desired options which is a good start. Now, my next challenge is to integrate a custom button at the end of the dropdown list for performing a specific action that is not ne ...

Does Vetur have additional undefined types in the type inference of deconstructed props?

When reviewing the code below, Vetur concluded that x,y are of type number | undefined. The presence of undefined is leading to numerous warnings when using x,y further in the code. Is there a way to eliminate the undefined from the type inference? <s ...

Placing a blank object after every line within a TypeScript array

I'm currently working on creating an iterator using the .map() function, specifically in this way: const csv = this.invoices .map(data => ({ invoiceId: data.invoiceId, invoiceDate: data.invoiceDate, invoiceType: data.invoiceType, ...

Hold off until all commitments are fulfilled in Firestore

Is there a way to ensure that all promises are resolved before moving on to the next line of code? Currently, it seems like it's moving to the next line without completing the operation below. I want to make sure that the forEach loop is fully execute ...

The custom error page in NextJS is failing to display

In my custom pages/404.ts file, I have coded the following: export default function NotFound() { return <h1>404 - Page Not Found</h1> } Additionally, there is another page that displays a 404 error when the organization is null: import Error ...

Why is my custom Vuelidate validator not receiving the value from the component where it is being called?

On my registration page, I implemented a custom validator to ensure that the password meets specific criteria such as being at least 12 characters long and containing at least one digit. However, I encountered an issue where the custom validator was not r ...

Error: The variable "document" is not defined in the context of NextJS TypeScript

Here is the import trace for the requested module: ./app/StarrySky.tsx ./app/resume/page.tsx ✓ Compiled in 425ms (711 modules) ⨯ app\StarrySky.tsx (9:4) @ document ⨯ ReferenceError: document is not defined Trying to set const vw equal to the ma ...

Is there a way to sort through nested objects with unspecified keys?

I'm looking to extract specific information from a nested object with unknown keys and create a new array with it. This data is retrieved from the CUPS API, where printer names act as keys. I want to filter based on conditions like 'printer-stat ...

What are some ways to troubleshoot the TypeScript React demonstration application in Chrome?

Debugging a TypeScript app in the Chrome debugger is a straightforward process. First, you need to configure the tsconfig.json file: "sourceMap": true, Next, install ts-node and set a breakpoint in your TypeScript code using "debugger;" ...