Vzans
Vzans

Reputation: 91

How to mock mongoose chaining query with jest

on test suite i want to mock model with chaining method findOne then select

LoginService

public loggingIn = async (loginDTO: LoginDTO) => {
    const user = await UserModel.findOne({ email : loginDTO.email }).select(['_id', 'username', 'email', 'password']);
    if (user) {
      const isPasswordMatching = await bcrypt.compare(loginDTO.password, user.password);
      if (isPasswordMatching) {
        const token = this.generateToken(user);
        const tokenDTO : TokenDTO = {
          access_token: token,
          expiresIn: loginConstant.EXPIRES_IN,
        };
        return tokenDTO;
      }
      throw new InvalidCrendentialsException();
    }
    throw new InvalidCrendentialsException();
  }

test

it('should return access_token when login is success', async () => {
      UserModel.findOne = jest.fn().mockResolvedValueOnce(UserFactory.successResponse);
      bcrypt.compare = jest.fn().mockResolvedValueOnce(true);
      const loginController = new LoginController();
      const app = new App([loginController]);

      const result = await request(app.getServer())
          .post(`${loginController.path}`)
          .send(loginFactory.validRequest);

      // expect(result.status).toBe(200);
      expect(result.body).toBe(200);
    });

errorMessage

user_model_1.default.findOne(...).select is not a function

Upvotes: 4

Views: 5213

Answers (1)

mgarcia
mgarcia

Reputation: 6325

For this to work, you need to define the mock so that the findOne method returns an object with the select method. An easy way to do this would be to define your mock as:

UserModel.findOne = jest.fn().mockImplementationOnce(() => ({ select: jest.fn().mockResolvedValueOnce(UserFactory.successResponse)}));

Upvotes: 11

Related Questions