【问题标题】:How to mock Mongoose 'find()' function in Jest?如何在 Jest 中模拟 Mongoose 'find()' 函数?
【发布时间】:2019-11-04 23:19:47
【问题描述】:

我有一个服务

export default class WorldService {

constructor(worldModel) {
    this.worldModel = worldModel;
  }

  async getWorlds() {
    let resData = {};
    await this.worldModel.find({}, (err, worlds) => {
      resData = worlds;
    });
    return resData;
  }
}

我有一个猫鼬模型

import mongoose from 'mongoose';

const worldSchema = mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
});

export default mongoose.model('World', worldSchema);

我想模拟 Mongoose 模型并测试名为 getWorlds() 的服务函数。我在我的项目中使用 Jest 作为测试框架。

我尝试用 Jest 写一个单元测试

import WorldModel from '../../../src/models/world';
import WorldService from '../../../src/services/world';

describe('When data is valid', () => {
  beforeAll(() => {
    jest.spyOn(WorldModel, 'find').mockReturnValue(Promise.resolve([
      { _id: '5dbff32e367a343830cd2f49', name: 'Earth', __v: 0 },
      { _id: '5dbff89209dee20b18091ec3', name: 'Mars', __v: 0 },
    ]));
  });

  it('Should return entries', async () => {
    const worldService = new WorldService(WorldModel);

    const expected = [
      { _id: '5dbff32e367a343830cd2f49', name: 'Earth', __v: 0 },
      { _id: '5dbff89209dee20b18091ec3', name: 'Mars', __v: 0 },
    ];
    await expect(worldService.getWorlds()).resolves.toEqual(expected);
  });
});

我得到一个失败的答案:

 FAIL  test/unit/services/world.test.js
  When data is valid
    × Should return entries (9ms)

  ● When data is valid › Should return entries

    expect(received).resolves.toEqual(expected) // deep equality

    Expected: [{"__v": 0, "_id": "5dbff32e367a343830cd2f49", "name": "Earth"}, {"__v": 0, "_id": "5dbff89209dee20b18091ec3", "name": "Mars"}]
    Received: {}

如何在 Jest 中模拟 Mongoose find() 函数?

附:我不喜欢为 MongoDB 使用任何更高级别的测试框架,例如 mockgoose

【问题讨论】:

    标签: javascript node.js mongodb mongoose jestjs


    【解决方案1】:

    您的服务有问题,如果您使用async await,则无需回调:

    export default class WorldService {
        constructor (worldModel) {
            this.worldModel = worldModel;
        }
    
        async getWorlds () {
            let resData = {};
    
            try {
                resData = await this.worldModel.find({});
            } catch (e) {
                console.log('Error occured in getWorlds', e);
            }
    
            return resData;
        }
    }
    

    我用它来模拟 mongoose 模型的 find 方法:

    describe('When data is valid', () => {
        beforeAll(() => {
            WorldModel.find = jest.fn().mockResolvedValue([{
                    _id: '5dbff32e367a343830cd2f49',
                    name: 'Earth',
                    __v: 0
                },
                {
                    _id: '5dbff89209dee20b18091ec3',
                    name: 'Mars',
                    __v: 0
                },
            ])
        });
    
        it('Should return entries', async () => {
            const worldService = new WorldService(WorldModel);
    
            const expected = [{
                    _id: '5dbff32e367a343830cd2f49',
                    name: 'Earth',
                    __v: 0
                },
                {
                    _id: '5dbff89209dee20b18091ec3',
                    name: 'Mars',
                    __v: 0
                },
            ];
            await expect(worldService.getWorlds()).resolves.toEqual(expected);
        });
    });
    

    【讨论】:

    • 为什么我们必须测试模型内容?什么时候需要?我通常只测试我的控制器。这还不够吗?
    • 我们不测试模型,我们只是模拟数据库层。这是服务测试而不是模型的
    猜你喜欢
    • 1970-01-01
    • 2021-02-27
    • 2019-04-09
    • 1970-01-01
    • 1970-01-01
    • 2021-03-28
    • 1970-01-01
    • 2018-09-14
    • 1970-01-01
    相关资源
    最近更新 更多