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
There's a couple of things that I notice here.
you're mocking the class that you're testing, meaning your tests are meaningless. You should instead mock the dependencies of it.
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.
Your allUsersList
will endup under the prototype
in the service
, kindly try
jest.spyOn(service.prototype,'allUsersList').mockImplementation(() => result);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With