笑话:如何使用MongoDB正确测试Javascript服务

问题描述 投票:0回答:2

我是Jest的初学者。

我使用依赖注入获得了UserService

public async getAll() {
  const userRecords = await this.userModel.find().select('name').catch((e) => {
    throw new HttpException(500, 'Error while fetching users.', e)
  });
  return <[IUser]>userRecords;
}

我想测试此功能。这是我可以运行的测试:

  1. 调用路由,并检查生成的JSON是否正常
  2. 获取数据库内容,并检查其是否符合预期
  3. 仅测试getAll功能

我认为1和2很明显,并且涵盖了不同的事物。 1覆盖请求部分,2覆盖DB部分。但是3号呢?如何“仅测试” getAll功能?

我已经尝试过:

const userModel = {
  find: (user) => {
    return [
      { id: 'user1' },
      { id: 'user2' }
    ]
  },
};
const userService = new UserService(userModel);
const userRecords = await userService.getAll();

expect(argumentRecord).toBeDefined();

但是很明显它失败了,因为select is undefined

我还应该嘲笑select()吗?我应该以不同的方式组织代码吗?

javascript mongodb testing jest
2个回答
1
投票

如果要编写此测试,我将使用jest.fn(implementation)模拟功能,以便可以在功能调用上实施期望。

jest.fn(implementation)

对函数调用的期望听起来似乎有些过激,但是它明确验证了const userQuery = { select: jest.fn(() => Promise.resolve([])) }; const userModel = { find: jest.fn(() => userQuery) }; const userService = new UserService(userModel); const userRecords = await userService.getAll(); expect(userRecords).toEqual([]); expect(userModel.find).toHaveBeenCalled(); expect(userQuery.select).toHaveBeenCalledWith('name'); 确实正在使用该模拟。

我还将以这样一种方式来构造测试,使得我可以测试各种代码路径而无需重新实现整个模拟。

getAll

此代码未经测试,因此可能无法正常工作,但希望它能充分概述该想法。


虽然这与您的问题没有直接关系,但我会避免将describe('getAll()', () => { let userQuery, userModel, userService; beforeEach(() => { userQuery = { select: jest.fn(() => Promise.resolve([])) }; userModel = { find: jest.fn(() => userQuery) }; userService = new UserService(userModel); }); afterEach(() => { expect(userModel.find).toHaveBeenCalled(); expect(userQuery.select).toHaveBeenCalledWith('name'); }); it('should get the user names', async () => { const users = [{ name: 'john' }, { name: 'jane' }]; userQuery.select.mockImplementation(() => Promise.resolve(users)); await expect(userService.getAll()).resolves.toBe(users); }); it('should handle errors', async () => { const error = new Error('Fake model error'); userQuery.select.mockImplementation(() => Promise.reject(error)); await expect(userService.getAll()).rejects.toMatch({ status: 500, message: 'Error while fetching users.', cause: error }); }); }); 与传统的承诺处理混在一起。

async/await

0
投票

是,您应该模拟public async getAll() { try { return <[IUser]> await this.userModel.find().select('name'); } catch (e) { throw new HttpException(500, 'Error while fetching users.', e) } } 。不仅如此,还可以检查函数内部使用的所有内容并测试它们是否正确执行。我会这样做:

select
© www.soinside.com 2019 - 2024. All rights reserved.