简体   繁体   中英

Jest: Cannot spy the property because it is not a function; undefined given instead getting error while executing my test cases

           This is my controller class(usercontoller.ts) i am trying to write junit test cases for this class  

            import { UpsertUserDto } from '../shared/interfaces/dto/upsert-user.dto';
            import { UserDto } from '../shared/interfaces/dto/user.dto';
            import { UserService } from './user.service';
                async updateUser(@BodyToClass() user: UpsertUserDto): Promise<UpsertUserDto> {
                    try {
                        if (!user.id) {
                            throw new BadRequestException('User Id is Required');
                        }
                        return await this.userService.updateUser(user);
                    } catch (e) {
                        throw e;
                    }
                } 

This is my TestClass(UserContollerspec.ts) while running my test classes getting error " Cannot spy the updateUser property because it is not a function; undefined given instead. getting error. However, when I use spyOn method, I keep getting TypeError: Cannot read property 'updateuser' of undefined:

*it seems jest.spyOn() not working properly where i am doing mistake. could some one please help me.the argument which I am passing?

    jest.mock('./user.service');

        describe('User Controller', () => {
            let usercontroller: UserController;
            let userservice: UserService;
            // let fireBaseAuthService: FireBaseAuthService;
            beforeEach(async () => {
                const module: TestingModule = await Test.createTestingModule({
                    controllers: [UserController],
                    providers: [UserService]
                }).compile();

                usercontroller = module.get<UserController>(UserController);

                userservice = module.get<UserService>(UserService);
            });

            afterEach(() => {
                jest.resetAllMocks();
            });

         describe('update user', () => {
             it('should return a user', async () => {
               //const result = new  UpsertUserDto();
               const testuser =  new  UpsertUserDto();
               const mockDevice = mock <Promise<UpsertUserDto>>();
               const mockNumberToSatisfyParameters = 0;
               //const userservice =new UserService();
               //let userservice: UserService;
                jest.spyOn(userservice, 'updateUser').mockImplementation(() => mockDevice);
              expect(await usercontroller.updateUser(testuser)).toBe(mockDevice);

          it('should throw internal  error if user not found', async (done) => {
            const expectedResult = undefined;
             ****jest.spyOn(userservice, 'updateUser').mockResolvedValue(expectedResult);****
             await usercontroller.updateUser(testuser)
              .then(() => done.fail('Client controller should return NotFoundException error of 404 but did not'))
              .catch((error) => {
                expect(error.status).toBe(503);
                expect(error.message).toMatchObject({error: 'Not Found', statusCode: 503});  done();
            });
        });
        });
        });

More than likely, your UserService class has other dependencies and as such, Nest cannot instantiate the UserService class. When you are trying to do userService = module.get(UserService) you are retrieving an undefined hence the error about jest.spyOn() . In unit tests, you should be providing a mock provider to take the place of your actual provider, like so:

describe("User Controller", () => {
  let usercontroller: UserController;
  let userservice: UserService;
  // let fireBaseAuthService: FireBaseAuthService;
  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [UserController],
      providers: [
        {
          provide: UserService,
          useValue: {
            updateUser: jest.fn(),
            // other UserService methods
          }
        }
      ],
    }).compile();

    usercontroller = module.get<UserController>(UserController);

    userservice = module.get<UserService>(UserService);
  });
  // rest of tests
});

Now when you retrieve the UserService you'll have an object with the proper functions back, which can then be jest.spyOn ed and mocked

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM