Cannot spyOn on a primitive value; undefined given in nestJS

12,414

Solution 1

There's a couple of things that I notice here.

  1. you're mocking the class that you're testing, meaning your tests are meaningless. You should instead mock the dependencies of it.

  2. You aren't mocking the dependencies of your class, so Nest cannot instantiate the class for you, meaning you are getting an undefined instead of a class.

To fix this, you'll want to do something like this:

beforeEach(async () => {
  const modRef = await Test.createTestingModle({
    providers: [
      UserService,
      {
        provide: getRepositoryToken(User),
        useClass: Repository,
      }
    ]
  }).compile();
  service = modRef.get(UserService);
  repository = modRef.get<Repository<User>>(getREpositoryToken(User));
});

And now you can mock the repository methods while still using the service to test the coverage.

There's a more in depth answer here and a repository full of test examples here. Feel free to take a look and dive a bit deeper.

Solution 2

Your allUsersList will endup under the prototype in the service , kindly try

jest.spyOn(service.prototype,'allUsersList').mockImplementation(() => result); 
Share:
12,414
mayur.pancholi
Author by

mayur.pancholi

Updated on June 13, 2022

Comments

  • mayur.pancholi
    mayur.pancholi almost 2 years

    I know this question is asked before but I'm having this error in nestjs when I run service test function

    here is my service code

    user.service.ts

    import { Injectable,HttpException, HttpCode, HttpStatus  } from '@nestjs/common';
    import { InjectRepository } from '@nestjs/typeorm';
    import { Repository } from 'typeorm';
    import { User } from './user.entity';
    import { UserRegisterAC } from '../application/userRegisterAC';
    
    @Injectable()
    export class UserService {
    
    constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>) {}
    
    async allUsersList(): Promise<User[]> {
     var users = this.userRepository.find();
    
     if(users==null){
      throw new HttpException("Users not found",HttpStatus.NOT_FOUND)
     }else{
      return users as unknown as User[];
     }
    }
    
    async create(userDTO: UserRegisterAC): Promise<User> {
    const user = new User();
    
    user.name = userDTO.name;
    user.phoneNo = userDTO.phoneNo;
    return this.userRepository.save(user);
    }
    }
    

    user.spec.ts

    import { Test, TestingModule } from '@nestjs/testing';
    import { UserService } from './user.service';
    
    
    describe('UserService', () => {
    let service: UserService;
    
    beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [UserService],
    }).compile();
    
    service = module.get<UserService>(UserService);
    });
    
    it('should return user array', async() => {
    const result = [{id:1,name:'mayur',phoneNo:'9998814695'}];
    // @ts-ignore
    jest.spyOn(service,'allUsersList').mockImplementation(() => result); 
    expect(await service.allUsersList()).toBe(result);
     });
    });
    

    In this file I want test allUserlist function in user service which return array of user. user entity contain id,name and phoneNo. when I run test I'm getting error like

    Cannot spyOn on a primitive value; undefined given
    
      17 |     const result = [{id:1,name:'mayur',phoneNo:'9998814695'}];
      18 |     // @ts-ignore
    > 19 |     jest.spyOn(service,'allUsersList').mockImplementation(() => result);
         |          ^
      20 |     expect(await service.allUsersList()).toBe(result);
      21 |   });
      22 | });
    

    Here is my jest config

    {
     "moduleFileExtensions": ["js", "json", "ts"],
     "rootDir": ".",
     "testEnvironment": "node",
     "testRegex": ".spec.ts$",
     "transform": {
     "^.+\\.(t|j)s$": "ts-jest"
    
    },
    "automock": true
    
    }
    

    I tried everything please give some suggestion