What are the best practices for testing a class function that executes a mongoose query?

Within my class, there are multiple class functions, with one specifically executing a mongoose query. The structure is similar to:

export class ExampleService {
  constructor(
    @InjectModel(Example.name) private exampleModel: Model<Example>,
    @InjectModel(MyMongoose.name) private myMongooseModel: Model <MyMongoose>
  ){}

  //function in focus for unit testing
  async addToCollection(name) {
    if(name.length < 1) throw new Error ('No name entered')
    else {
      this.myMongooseModel.query()
    }
  }

  //..other functions that utilize addToCollection()

}

My goal is to test the behavior of addToCollection() by ensuring it throws an error when name is too short, and that it initiates a query to myMongooseModel when the name is sufficient.

Past attempts at mocking ExampleService led to having to mock not only addToCollection but also the query to myMongooseModel. This approach seems incorrect for testing this specific function. How can I solely mock the call to myMongooseModel?

Answer №1

myMongooseModel is an essential dependency that can be easily mocked by creating a spy object and injecting it into the ExampleService.

For example:

describe("ExampleService", () => {
  let service: ExampleService;

  let exampleModelMock;
  let myMongooseModelMock;

  let logSpy;

  beforeEach(() => {
    logSpy = jest.spyOn(console, 'log'); // spying on the log function
    exampleModelMock = {}; // mocking the example model
    myMongooseModelMock = {
      query: jest.fn(), // mocking the query function
    };

    service = new ExampleService(exampleModelMock, myMongooseModelMock); // injecting dependencies
  });

  it("should NOT call query when name is too short", async () => {
    await service.addToCollection("");

    expect(logSpy).toHaveBeenCalledWith('no name entered');
    expect(myMongooseModelMock.query).not.toHaveBeenCalled();
  });

  it("should call query when name is NOT too short", async () => {
    await service.addToCollection("long_name");

    expect(logSpy).not.toHaveBeenCalled();
    expect(myMongooseModelMock.query).toHaveBeenCalled();
  });
});

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

Encountering an Uncaught TypeError when attempting to set properties of null with useRef

I've been working on an app that requires access to the user's device camera in order to display live video on the screen. I've managed to achieve this by utilizing a video HTML Object and setting the media stream as its srcObject. Everythin ...

Variables in Angular DI become undefined when a method is called through a passed function reference

Utilizing Angular, I have a class with several Dependency Injection (DI) variables. During normal execution of a method within the class, everything functions as expected and I can access the injected instances of the DI variables. Now, my goal is to crea ...

The value returned by Cypress.env() is always null

Within my cypress.config.ts file, the configuration looks like this: import { defineConfig } from "cypress"; export default defineConfig({ pageLoadTimeout: 360000, defaultCommandTimeout: 60000, env: { EMAIL: "<a href="/cdn-cgi/ ...

What is the reason for Record accepting an array in TypeScript?

I'm puzzled as to why this code compiles in typescript. I've tried researching and checking the typescript documentation, but still can't find the answer. type RecType = Record<string, any> const arr: RecType = [1, 2, "three" ...

Steps for verifying the state update following an API response

I am currently performing unit testing using jest and enzyme on my ReactJS code. I have a main functional component called "TrashDisplayFiles" in which there is a method named "getDeletedData". This method makes an API call to set the TrashFileState based ...

Easily Organize Your Data with Kendo React Grid: Rearrange Columns and Preserve Your Custom Layout

Currently, I am working on implementing a Kendo React grid with the option set to reorderable={true} for allowing column reordering. However, I am facing difficulty in determining how to save the new order of columns. Which event should I use to detect whe ...

Leverage rxjs/Typescript to transform an array nested within the data received from an external API

Exploring Typescript/Javascript is a new adventure for me, especially as I delve into the world of rxjs. Here's a snippet of code that I've been working with: return this.http.get<IXenoCantoResponse>(`${this.corsAnywhereUrl}${this.xenoCant ...

Encountered a hiccup while trying to pull in the StorageProvider class from aws-amplify

According to the documentation provided by AWS Amplify: import { Storage, StorageProvider } from 'aws-amplify'; export default class MyStorageProvider implements StorageProvider { Check out this link for more information. Encountering an error ...

The maximum nested function level has been reached at tsc:1. Consider increasing the FUNCNEST limit

Having an issue while trying to compile a typescript file, encountering the following error: work/gigMax [typescriptMigration●] » tsc src/mutate.ts tsc:1: maximum nested function level reached; increase FUNCNEST? work/gigMax [typescriptMigration●] ...

There is no unbind() method available

Using jasmine to perform tests on an application powered by AngularJS. The function is simple, it checks for the 'activate' value and scrolls. If the 'scroll' value surpasses the 'activate' value, the function should be unboun ...

Mocking a common function in a shared service using Typescript and Jest

I have a service that is utilized with NestJS, although the issue at hand is not specific to NestJS. Nonetheless, testing in NestJS is involved, and I use it to create the service for testing purposes. This service is responsible for making multiple calls ...

What steps can be taken to troubleshoot and resolve this specific TypeScript compilation error, as well as similar errors that may

I am struggling with this TypeScript code that contains comments and seems a bit messy: function getPlacesToStopExchange(): { our: { i: number; val: number; }[]; enemy: { i: number; val: number; }[]; //[party in 'our' | 'enemy' ]: ...

Update the form field with today's date in a JHipster application

In our current project in JHipster, we are facing a challenge with setting the default value of a form field as the current date. JHipster offers a moment format for dates, which is essentially an ngbdatepicker. However, when attempting to change the inpu ...

Typescript raises an error when providing a potentially null value (that is not null) to an unnamed callback function

When dealing with a property that starts as null, how can I pass it to an anonymous callback function expecting a non-null value without TypeScript throwing errors? I've tried wrapping the function call in an if statement to check for null at the cal ...

Discovering how to properly run tests on a function within an if statement using Jasmin, Karma

I've recently started unit testing and I'm facing an issue with my component. The component calls a service to display a list of students. getListStudents() { this.noteService.getStudents({}).subscribe(res => { this.students= res })} Then ...

Encountering "Error: Unable to access properties of null (reading 'isCE')" issue during upgrade from version 3.2.37 to 3.2.39 of Vue

After upgrading Vue in my project from 3.2.37 to 3.2.39, running Jest now results in the following error: [UnhandledPromiseRejection: This error occurred due to either throwing inside an async function without a catch block, or rejecting a promise that was ...

What steps can be taken to ensure that a second Pinia plugin waits for the completion of the

I am currently developing a Vue application with Pinia as the state manager. I have created two plugins - one for authentication and another to set up my API instance. The second plugin relies on the token obtained from the first plugin. Upon analyzing th ...

The generic does not validate the types of two properties

type ComponentType = (...args: any) => any; type PlatformNotificationProps<TIcon extends ComponentType = ComponentType> = { component: TIcon; arg: Parameters<TIcon>[0]; }; const PlatformNotification = (props: PlatformNotificationProps) ...

Can you explain the functionality of this code snippet from a slate.js demonstration?

Trying to grasp the concepts of Slate.js, I delved into the rich text example. Within it, I encountered a code snippet that has left me puzzled. const isBlockActive = (editor, format) => { const [match] = Editor.nodes(editor, { match: n => ...

django fixture unit testing - no matching object in query

I'm currently setting up unit testing in Django using fixtures for my project. Although I can successfully load my fixtures, I encounter an error when trying to retrieve data from them: DoesNotExist: BlogIndexPage matching query does not exist. Thi ...