Troubleshooting issues with setting up Jest in an Express project

I'm having trouble creating tests for an API built with Express and TypeScript. I keep encountering strange errors during compilation and mocking configurations. Here are my files:

/test/unit/services/episodeService.spec.ts

/*some imports*/

describe('Episodes Service', () => {

    let episodesQueryServiceMock: jest.Mocked<typeof episodesQueryService>
    let watchTimeInstance: jest.Mocked<WatchTimeInstance>

    beforeEach(() =>{
        jest.mock('../../../src/services/queries/episodesQueryService')
        jest.mock('../../../src/models/')
        jest.mock('../../../src/models/WatchTime')
        episodesQueryServiceMock =  episodesQueryService as jest.Mocked<typeof episodesQueryService>
    })

    it('When there is no WatchTime, then create it', async ()=> {
        const watchTime: WatchTime =  watchTimeFactory.build() 
        (episodesQueryServiceMock.findByUserIdAndEpisodeId as jest.Mock).mockReturnValue(watchTime)
        (watchTimeInstance.save as jest.Mock).mockReturnValue(watchTime)
        const actual = await episodesService.setWatchTime(watchTime)
    })

})

In the code above, I encountered an error in the first line of my test case.

This expression is not callable. Type 'WatchTime' has no call signatures.ts(2349)

The issue seems to be with using a factory to generate random objects for testing, as shown in my factory file below:

./test/factories/watchTime.ts

/*some imports*/
export const watchTimeFactory = Factory.makeFactory<WatchTime>(() => ({
    userId: Number(faker.random.numeric()),
    episodeId: Number(faker.random.numeric()),
    seconds: Number(faker.random.numeric()),
    createdAt: new Date(),
    updatedAt: new Date()
}))

I initially thought it was a problem with the factory library, but I encountered the same error with two different factory libraries. However, if I move the factory call outside the test case, the error disappears, but a new error arises when running the test:

TypeError: episodesQueryServiceMock.findByUserIdAndEpisodeId.mockReturnValue is not a function

Here are my Jest configurations:

./jest.config.ts

import type {Config} from '@jest/types';
// Sync object
const config: Config.InitialOptions = {
    verbose: true,
    transform: {
        '^.+\\.tsx?$': 'ts-jest',
    },
    setupFiles: ['<rootDir>/test/setup.ts'],
    testEnvironment: 'node',
    maxWorkers: 1,
    preset: 'ts-jest'
};
export default config;

./test/setup.ts

import dotenv from 'dotenv'
dotenv.config()

process.env.DATABASE = process.env.DATABASE?.replace(/_development/, '_test')

I believe the errors I am facing are related to the configuration settings. Any help would be greatly appreciated.

Thank you!

Answer №1

After thorough troubleshooting, I have identified two issues in my code:

1st) The problem lies in my factory code, where the correct implementation should be:

import * as Factory from "factory.ts";
import { faker } from '@faker-js/faker'
import { WatchTime } from '../../src/models'

export const watchTimeFactory = Factory.makeFactory<WatchTime>({
    userId: Number(faker.random.numeric()),
    episodeId: Number(faker.random.numeric()),
    seconds: Number(faker.random.numeric()),
    createdAt: new Date(),
    updatedAt: new Date()
});

2nd) My usage of jest.mock() is incorrect as it needs to be within the same context as my imports:

import { episodesService } from "../../../src/services/episodesService"
import { episodesQueryService } from "../../../src/services/queries/episodesQueryService"
import { WatchTime } from "../../../src/models/"
import { WatchTimeInstance } from "../../../src/models/WatchTime"
import { watchTimeFactory } from "../../factories/watchTime"

// Correct placement
jest.mock('../../../src/services/queries/episodesQueryService')
jest.mock('../../../src/models/')
jest.mock('../../../src/models/WatchTime')

describe('Episodes Service', () => {

    it('When there is no existing watchTime, create a new one', async ()=> {
        const watchTime =  watchTimeFactory.build();
        (episodesQueryService.findByUserIdAndEpisodeId as jest.Mock).mockReturnValue(watchTime);
        const actual = await episodesService.setWatchTime(watchTime);
    })

})

Following these modifications resolved the issues encountered. Thank you for your assistance.

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 problem when attempting to incorporate fade in/fade out effect animation

I have a webpage that features multiple buttons, each triggering a fade-in/fade-out animation when clicked. This animation also involves changing the contents of a specific div. Though everything is functioning properly, there is a brief moment (about hal ...

angular2 fullCalendar height based on parent element

Currently, I am using angular2-fullcalendar and encountering an issue with setting the height to 'parent'. The parent element is a div but unfortunately, it does not work as expected. The navigation bar appears fine, however, the calendar itself ...

Angular httpClient: Adjusting date format within json object

I need help converting the date property of an object to a format that the server can understand when using httpClient.post(...). Currently, the date property has its natural string representation. What steps can I take to make sure it is in the correct ...

I encountered an issue with Typescript Jest where it was unable to find the mock or mockReturnedValue functions on the types I

Let's test out this interesting class: //RequestHandler.js import axios, {AxiosInstance} from 'axios'; import settings from './settings'; const axiosHandler: AxiosInstance = axios.create({ baseURL: 'http://localhost:8081&a ...

Is there a way to streamline this query code that seems overly complex?

Could someone please assist me in simplifying this code? I am trying to shorten or simplify the query code by using a stored procedure, but I still need to include the details inside the "()" parentheses. I am new to Node.js and would appreciate any help. ...

Troubleshooting Primevue Data table styling issues in Vue3

Currently, I am attempting to incorporate grids into my data table using primevue library. However, despite following the provided example at https://www.primefaces.org/primevue/datatable/dynamiccolumns, the gridlines are not appearing on the table. The c ...

Is there a problem with the transition table in my negamax algorithm implementation?

I'm currently developing a Chess AI in TypeScript that utilizes negamax with alpha-beta pruning to explore potential moves. The AI incorporates two heuristics: 1) the main heuristic, which assesses leaf nodes during the negamax tree traversal, and 2) ...

When configuring the Redux logger, the type 'Middleware<{}, any, Dispatch<UnknownAction>>' is not compatible with type 'Middleware<{}, any, Dispatch<AnyAction>>'

In my React project, I have defined the redux logger with the package version "redux-logger": "^3.0.6" in the file store.ts as shown below: import { configureStore } from '@reduxjs/toolkit'; import rootReducer from '@/re ...

Unable to handle errors when making API requests

I'm currently working on a custom hook and I need to handle errors that may occur during an API call to adjust the display. Here's the code for the custom hook: function useBook() { const [book, setBook] = useState<Book | any>() con ...

`Struggling with managing callbacks, handling errors, and working with MongoDB`

I recently revamped my code for an application that handles adding companies to a database. In the past, my code was messy and unorganized, so I decided to structure it properly by introducing routes, a controller, and a data access object. Here is how my ...

The ts-mocha test does not play well with the use of node-fetch library

I have set up ts-mocha and node-fetch to run a unit test, but I am encountering the following error: TypeError: Unknown file extension ".ts" for ... The content of the file is as follows: import fetch from 'node-fetch'; export defau ...

Setting up a .travis YAML file for Django and Travis CI to smoothly start a localhost server before running tests without any delays

Setting up a CI environment for my Django project has been quite the challenge. I'm currently struggling with getting travis to work properly. When testing my code locally, I have to first run 'manage.py runserver' to start the server and th ...

Allowing the user to change their password while logged in

I have a straightforward login/register controller where users can create an account and sign in. Here is my signin function with roles: exports.signin = (req, res) => { User.findOne({ where: { username: req.body.username } }) .th ...

Is there a way to load an image onto the ngx-image-cropper without triggering the imageChangedEvent event?

My latest project involved creating a custom cropper using ngx-image-cropper, which allows for cropping and rotating images. For the sprint demo, I needed the images to be displayed as soon as the application loads without having to trigger the fileChangeE ...

I am struggling to extract data from the spawned Node.js child process. What am I overlooking?

Trying to utilize a spawned command-line process for lzip in order to expand an lzipped data stream due to the lack of suitable native JavaScript tools. Succeeded in achieving this by working with files and file descriptors, although cumbersome to handle ...

A guide to iterating over an array and displaying individual elements in Vue

In my application, there is a small form where users can add a date with multiple start and end times which are then stored in an array. This process can be repeated as many times as needed. Here is how the array structure looks: datesFinal: {meetingName: ...

Unable to retrieve jwt token from cookies

Currently, I am developing a website using the MERN stack and implementing JWT for authentication. My goal is to store JWT tokens in cookies. Despite invoking the res.cookie function with specified parameters (refer to the code below), I am facing difficul ...

gather and handle data from the shared interface between different parts

I have two different paths. One is for products and the other is for products-cart. I want to use a shared ts file for both to store the product and cart information in an array. However, I am encountering an issue. I am unable to make any changes or trans ...

Encasing distinct HTML text with a custom color palette

How can I create a specific color scheme for my HTML table's Status parameter, where the values can be SUCCESS, FAILURE, or IN PROGRESS? I'm utilizing Angular 4 (HTML and TypeScript) for this task. Any tips on how to achieve this? ...

The Console.Log function will not run if it is placed within the RXJS Tap operator

In my current setup, I have the following observables: this.authenticationService.isSignedIn() -> Observable<Boolean> this.user$ -> Observable<UserModel> I am in need of checking a condition based on both these observables, so I attempt ...