Using NestJS, TypeScript, Jest resulted in an error: "TypeError: Cannot read property 'pipe' of undefined."

To test the functionality of `uploadFile` that uploads a file to a Google Storage bucket using Jest, I need to mock the `createReadStream` function on the File object.

Code snippet from `my-service.ts`:

async uploadFile(file: FileUpload): Promise<{
url: string
path: string}> {
 try {
  file.createReadStream().pipe(
   bucket
    .createWriteStream({
     ...some options
    })
    .on('error', (err) => {
     reject(err)})
    .on('finish', async () => {
     resolve({
      url: 'file-url',
      path: 'file-path'
     })
    })
   
 }
}

Test case in `my-service.spec.ts`:

  describe('#uploadFile', () => {
    it('uploads file', async () => {
      const bucketMock = new Bucket('the-bucket-mock')
      const bucketFileMock = new File(bucketMock, 'the-file')

      const fileUploadMock = {
        filename: 'the-file',
        mimetype: 'mimetype',
        encoding: 'encoding',
        createReadStream: jest.fn().mockImplementation((stream) => {
          pipe: jest.fn()
        }),
      }

      jest
        .spyOn(fileUploadMock, 'createReadStream')
        .mockImplementation((stream) => {
          stream.pipe()
          return Promise.resolve({
            url: 'url-result',
            path: 'file-path-result',
          })
        })

      const uploadFileResult = await myService.uploadFile(fileUploadMock)

      expect(uploadFileResult).toBeCalled()
    })
  })

Answer №1

Your code snippet:

        createReadStream: jest.fn().mockImplementation((stream) => {
          pipe: jest.fn()
        }),

may not be functioning as expected. It seems like you intended for the function passed into mockImplementation to return an object with a {pipe: jest.fn()} structure, but that's not quite accurate. When using an arrow function and having an open curly bracket immediately after the arrow, it changes the behavior of returning values in TS/JS.

// This returns undefined
function (stream) {
  pipe: jest.fn()
}

To address this issue, consider tweaking your code like so:

(stream) => {
  return { pipe: jest.fn() };
}

If you prefer a more concise syntax, ensure that the first character after the arrow is not an opening curly bracket:

// Wrap the object in parentheses
(stream) => ({
  pipe: jest.fn()
})

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 IO type to an array of Either in functional programming with the fp-ts

Looking for assistance with implementing this in fp-ts. Can someone provide guidance? const $ = cheerio.load('some text'); const tests = $('table tr').get() .map(row => $(row).find('a')) .map(link => link.attr(&apos ...

Having trouble retrieving the position of an element while using @ViewChild in Angular 6 to create a sticky element

While working with Angular 6, I am attempting to create a table header that remains centered on the page until the user scrolls past it, at which point it should stick to the top of the page. I am using @ViewChild to try and grab the position of this eleme ...

The inability to utilize custom images as icons with the "icon" property is a limitation for Android and IOS development in NativeScript

Having some trouble with the "icon" property in the Navigation button tag to use a custom image as an icon. On Android, it's working fine, but on iOS the image appears oversize. I've tried using scss and setting height in the tags themselves wit ...

Revise the classification of an instance variable within a subclass

I am pondering about the topic of inheritance and types for instance variables in typescript. Consider a basic class as shown below: class Person { instanceVariable: Object; age: Number; constructor(instanceVariable: Object, age: Number) { this ...

What could be causing the TypeScript type error within this Effector effect subscriber?

Working on a front-end application utilizing React, Typescript, Effector, FetchAPI, and other technologies. Created an Effector effect to delete an item in the backend: export const deleteItemFX = createEffect({ handler: (id: string) => { return ...

Adding React with TypeScript to an existing ASP.NET Core MVC application: A step-by-step guide

Can anyone suggest a reliable method to integrate react components (typescript) in the form of .tsx files into my asp.net core mvc .cshtml pages? I've been encountering issues trying to make it work successfully. Any insights or advice would be greatl ...

Guide to using Jest for monitoring a class property arrow function

Is there a way to effectively test a class property arrow function in Jest? The current test case I have is encountering the error message Expected mock function to have been called.: import React, {Component} from "react"; import {shallow} from "enzyme"; ...

What is the process for defining the default landing page route in Angular routing?

My application currently has only one route, and I want it to start with the URL http://localhost:4200/specialtyQ. However, my application is not loading properly. The code snippet below is what I am using to try to achieve this. How can I correct the URL ...

The issue of session type not updating in Next.js 14 with Next-auth 5 (or possibly version 4) is a common concern that needs to

Experimenting with new tools, I encountered an issue when trying to utilize the auth() function to access user data stored within it. TypeScript is indicating that the user does not exist in Session even though I have declared it. Here is my auth.ts file: ...

What is the reason for TypeScript's prioritization of arguments over assignment in generic inference?

When it comes to Typescript generics inference, the priority is given to arguments over assignment. This means that any param props are automatically converted into type unknown, even if they are assigned to a variable whose type param is set to an object ...

Is there a way to manage the rendering of a child component when using the .map() method?

I have a task that involves adding animation to the first element of an array. Currently, when data updates, my parent and child components both rerender, causing the animation to play multiple times on all elements in the array added to the child simultan ...

What is the method to define a loosely typed object literal in a TypeScript declaration?

We are currently in the process of creating TypeScript definitions for a library called args-js, which is designed to parse query strings and provide the results in an object literal format. For example: ?name=miriam&age=26 This input will produce th ...

Converting ASP .Net Core Dto's and Controllers into TypeScript classes and interfaces

My concept involves incorporating two key elements: Converting C# Dto's (Data-transfer-objects) into TypeScript interfaces to ensure synchronization between client-side models and server-side. Transforming ASP .Net Core controller endpoints into Typ ...

Executing multiple queries in a node.js transaction with Sequelize using an array

I am looking to include the updates on the clothingModel inside a transaction, with the condition that if it successfully commits, then update the reservationModel. This is the snippet of code I am attempting to refactor using sequelize.transaction tr ...

What could be causing the User object in the auth0/nextjs useUser hook to have missing properties?

The user object retrieved using the useUser hook from auth0/nextjs package seems to be missing some important properties: { "nickname": "example", "name": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bedbc6dfd3ced2dbfec7 ...

Combining ReactJS event handling for onClick and onKeyDown into a single handler for TypeScript

To ensure accessibility compliance, I am incorporating onKeyPress handlers into my application. However, I am facing a challenge with interactive <div /> elements. Here are the event handlers I want to trigger on click: const handleViewInfoClick = ( ...

TS2350 Enzyme Note: The 'new' keyword can only be used with a void function

Following the setup below: import * as enzyme from 'enzyme'; import * as Adapter from 'enzyme-adapter-react-16'; enzyme.configure({ adapter: new Adapter() }); When I use jest --watch, everything runs smoothly. However, when I try web ...

Convert an object to nested JSON in Angular 5

I am struggling with using Angular 5 HttpClient to send a post request because I am having trouble casting an object to nested JSON. For instance, I have the following class: export class Team { members: Person[]; constructor(members: Person[]) ...

Guide to reference points, current one is constantly nonexistent

As I work on hosting multiple dynamic pages, each with its own function to call at a specific time, I encounter an issue where the current ref is always null. This poses a challenge when trying to access the reference for each page. export default class Qu ...

Having trouble accessing the database in Angular and Ionic through a provider on a Tabbed page

I created a Home page with tabs using Ionic 3 and Angular. The tabs are named Stats and Calc. When clicking on the Stats tab, it triggers the class/component stats.ts (displayed below). This component utilizes two providers: CropProvider and ContractProvi ...