Having trouble getting Jest to manually mock in Nestjs?

When setting up a mock service like this:

// /catalogue/__mock__/catalogue.service.ts
export const CatalogueService = jest.fn().mockImplementation(() => {
  return {
    filterRulesFor: jest.fn().mockImplementation((role: Roles): Rule[] => rules.filter(r => r.roles.includes(role))
    fetchCountries: jest.fn().mockReturnValue(of(countriesStub())),
  }
});

In the upcoming structure:

/catalogue
  /__mock__
    catalogue.service.ts
  /tests
    catalogue.controller.spec.ts
  catalogue.module.ts
  catalogue.controller.ts
  catalogue.service.ts

The goal is to utilize the mock service within the catalogue.controller.spec.ts:

// /catalogue/tests/catalogue.controller.spec.ts
import { CatalogueController } from '../catalogue.controller';
import { CatalogueService } from '../catalogue.service';

jest.mock('../catalogue.service'); // <----- manual mocking here

describe('CatalogueController', () => {
  let controller: CatalogueController;
  let service: CatalogueService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      imports: [UtilsModule],
      controllers: [CatalogueController],
      providers: [CatalogueService],
    })
    .compile();

    controller = module.get<CatalogueController>(CatalogueController);
    service = module.get<CatalogueService>(CatalogueService);
    jest.clearAllMocks();
  });
}

However, encountering an issue when attempting to use it:

describe('getCountries', () => {
  let countries: Country[];
  beforeEach(async () => {
    service.fetchCountries()
    .subscribe(countries => console.log(countries)); // <----- here

    countries = await firstValueFrom(controller.getCountries());
  });

  it('should be called', () => {
    expect(service.fetchCountries).toBeCalledTimes(1);
  });

  it('should not be empty', () => {
    expect(countries.length).toBe(countriesStub().length);
  });
});

Getting a

TypeError: Cannot read property 'subscribe' of undefined
as though the mock service doesn't have the required functions defined.

https://i.sstatic.net/N2mKL.png

If including the mock directly in the same file it works, but that's not the preferred approach:

let controller: CatalogueController;
let service: CatalogueService;

// vvvvv Mock service here vvvv
const mockCatalogueService = {
  filterRulesFor: jest.fn().mockImplementation((role: Roles): Rule[] => rules.filter(r => r.roles.includes(role))),
  fetchCountries: jest.fn().mockReturnValue(of(countriesStub())),
};

beforeEach(async () => {
  const module: TestingModule = await Test.createTestingModule({
    imports: [UtilsModule],
    controllers: [CatalogueController],
    providers: [CatalogueService],
  })
  .overrideProvider(CatalogueService) // <--- Implementing here
  .useValue(mockCatalogueService)     // <--- and here
  .compile();

  controller = module.get<CatalogueController>(CatalogueController);
  service = module.get<CatalogueService>(CatalogueService);
  jest.clearAllMocks();
});

Answer №1

In jest, manual mocking can be done using the import statement. However, Nestjs takes a different approach by implementing Dependency Injection (DJ). This means that certain objects like services and controllers are obtained from a container that holds all instance objects of the application. You can experiment with this method:

import { CatalogueService } from '../catalogue.service';

jest.mock('../catalogue.service');
//...
const module: TestingModule = await Test.createTestingModule({
  imports: [UtilsModule],
  controllers: [CatalogueController],
  providers: [CatalogueService],
})
.useMocker((token) => {
  switch (token) {
    case CatalogueService:
      return CatalogueService;
    // more mock objects can be added here
  }
})
.compile();

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

Issue with Angular not sending data to ASP.net server

Attempting to send data to my asp.net server using angular. After testing the front-end data, the issue arises when sending the data with a post request; angular sends null data instead. Interestingly, when sending the same data to the server from Postman, ...

declare wrong TypeScript type in external library

I am currently using winston 3.0 in combination with the @types/winston types. Unfortunately, it seems that these types are not completely compatible, leading to an error in the types that I am unsure how to rectify. Below is the code snippet in question: ...

Typescript: Assigning Variables Without Prior Declaration

In my upcoming Node.js application, I decided to use TypeScript for development. However, I encountered a perplexing issue while working on the code below: class AuthService { public async init(req: Request, res: Response) { let user: IUser | ...

NG0900: Issue encountered while attempting to compare '[object Object]'. Please note that only arrays and iterable objects are permitted for comparison

Experimenting with an Angular project where I am retrieving data from a Minecraft API and displaying it on my website. This is my first time working with Angular's HTTP requests. Encountered the following error code; NG0900: Error trying to diff &apo ...

Experiencing a console error which reads: "SyntaxError: Missing ) after argument list."

While working on configuring a new React CSR app and incorporating some boilerplate libraries, I encountered an error in the console: Uncaught SyntaxError: missing ) after argument list (at @emotion_react_macro.js?v=30f6ea37:29894:134) I am hesitant to ma ...

"Type 'Unknown' cannot be assigned to the specified type: Typescript Error encountered while using

I encountered an error message in my Redux Observable setup. Any advice on how to resolve this issue? The error states: 'Argument of type 'OperatorFunction<ITodo[], Action<{ params: { url: string; }; } & { result: { todos: ITodo[]; }; ...

Tips on creating a literal type that is determined by a specific value within an object

In the flow, I am able to create a dynamic literal type in this manner: const myVar = 'foo' type X = { [typeof myVar]: string } const myX: X = { foo: 1 } // will throw, because number const myX: X = { foo: 'bar' } // will not throw ...

Error in sending data to the server via the specified URL: "Http failure response for http://localhost/post.php: 0 Unknown Error" and POST request to http://localhost/post.php failed with error code

Feeling a bit stuck trying to add data to my database. As a junior with PHP and Angular, I am using PHP via XAMPP and Angular 8. Is it possible to create separate files for the post and get methods in the PHP file? app.component.ts import { Component, O ...

"Improve your Angular ngrx workflow by utilizing the sandbox pattern to steer clear of

Currently, I'm trying to determine whether my implementation of the ngrx and sandbox pattern is effective. Here's the issue I'm facing: getFiles(userId: number, companyId: number) { this.fileService.getFiles(userId, companyId).subscribe(re ...

What is the best approach to dynamically update CSS using onChange in TypeScript?

I am facing an issue with 2 input fields on my website. I want to create a functionality where if a user enters data into one field, the CSS of the other field changes dynamically. For instance, I would like to change the class "changeAmount" to "display:n ...

Instead of returning an object, the underscore groupBy function now returns an array

Currently, I am attempting to utilize underscore to create an array of entities that are grouped by their respective locations. The current format of the array consists of pairs in this structure { location: Location, data: T}[]. However, I aim to rearran ...

Declaring TypeScript functions with variable numbers of parameters

Is it possible to define a custom type called OnClick that can accept multiple types as arguments? How can I implement this feature so that I can use parameters of different data types? type OnClick<..> = (..) => void; // example usage: const o ...

Having Trouble Adding Details to a New Cart for a User in Angular and MongoDB - What's Going On?

After working on an E-Commerce site for a while, I hit a roadblock. Despite taking a break and coming back with determination, I can't seem to resolve the issue at hand. The application features registration, login, product search, and a popup window ...

What is the most effective method for pausing execution until a variable is assigned a value?

I need a more efficient method to check if a variable has been set in my Angular application so that I don't have to repeatedly check its status. Currently, I have a ProductService that loads all products into a variable when the user first visits the ...

Navigating the NextJS App Directory: Tips for Sending Middleware Data to a page.tsx File

These are the repositories linked to this question. Client - https://github.com/Phillip-England/plank-steady Server - https://github.com/Phillip-England/squid-tank Firstly, thank you for taking the time. Your help is much appreciated. Here's what I ...

Error message: "Error encountered while building Next.js - ReferenceError: 'describe' is not defined"

I am facing difficulties achieving a successful next build without encountering the following error: > Build error occurred { ReferenceError: describe is not defined Although the dev server and tests execute smoothly, it appears that the jest global d ...

Having trouble with implementing custom checkboxes in a d3 legend?

My attempt at creating checkboxes in d3 has hit a snag. Upon mouse click, the intention is for them to be filled with an "x". Strangely, using d3.select() inside the click-function doesn't seem to work as expected, although adding the letter U for the ...

In search of assistance with resolving a React Typescript coding issue

I need help converting a non-TypeScript React component to use TypeScript. When attempting this conversion, I encountered the following error: Class 'Component' defines instance member function 'componentWillMount', but ext ...

Trying out the Material-UI Textfield select component using jest testing framework

Currently, I am in the process of writing a test to validate a basic Material-UI Textfield select component. The objective of this test is to demonstrate that selecting an option triggers the corresponding event. Below is the representation of the compone ...

Creating a Vue Directive in the form of an ES6 class: A step-by-step

Is it possible to make a Vue directive as an ES6 Class? I have been attempting to do so, but it doesn't seem to be working correctly. Here is my code snippet: import { DirectiveOptions } from 'vue'; interface WfmCarriageDirectiveModel { ...