首页 > 解决方案 > 使用 Jest 测试具有数据库调用的函数

问题描述

我是 Jest 和一般代码测试的新手。我想测试一个使用 mongoose 从 mongodb 数据库中检索数据的函数。当我运行测试时,我正在测试的函数中对 db 的所有调用都返回 null。测试需要从数据库中检索数据的函数的推荐方法是什么?

如果您需要代码示例或更多信息,请告诉我。

更新:

这是我的代码:

代码.js

...
function buildText(listing, messageRule, reservation, isReview = false, isLastMinuteMessage = false) {
    return new Promise(async function(resolve) {
        const name = reservation.name;
        try {
            message = await Message.findOne({
                listingID: listing._id,
                messageRuleID: messageRule._id,
                reservationID: reservation._id,
                message: {$exists: true}
            });
        } catch (error) {
            console.error(error);
        }
        if (message) {
            text = message.message;
        } else {
            text = messageRule.message;
            if (isLastMinuteMessage) {
                text = messageRule.lastMinuteMessage;
            }
        }
        text = text.replace(/{{Guest Name}}/g, name);
        resolve(text);
    });
}
...

代码.test.js

const Code = require("./code");
describe("funcs", () => {
    it("buildText", async () => {
        let listing = {
            _id: "1324",
            pricingEnabled: true,
            listingFound: true,
            hideListing: null
        };
        let messageRule = {
            _id: "3452345",
            minNights: 1,
            reviewEnabled: false,
            disableMessageAfterReview: false,
            message: 'test',
            lastMinuteMessage: 'test2'
        };
        let reservation = {
            _id: "63452345",
            hasLeftReview: true,
            hasIssues: false
        };
        let isReview = false;
        let isLastMinuteMessage = false;
        let response = await Code.buildText(listing, messageRule, reservation, isReview, isLastMinuteMessage);
        expect(response).toMatchSnapshot();
    });
});

我遇到的麻烦是message = await Message.findOne({我的代码文件中的行。它总是返回 null,但我需要能够告诉它返回 true 或 false。我怎样才能做到这一点?

标签: mongodbmongoosejestjs

解决方案


这是一个基于提供的代码的简单工作示例:


代码.js

const { Message } = require('./message');

function buildText(listing, messageRule, reservation, isReview = false, isLastMinuteMessage = false) {
  return new Promise(async function (resolve) {
    let message, text;
    const name = reservation.name;
    try {
      message = await Message.findOne({
        listingID: listing._id,
        messageRuleID: messageRule._id,
        reservationID: reservation._id,
        message: { $exists: true }
      });
    } catch (error) {
      console.error(error);
    }
    if (message) {
      text = message.message;
    } else {
      text = messageRule.message;
      if (isLastMinuteMessage) {
        text = messageRule.lastMinuteMessage;
      }
    }
    text = text.replace(/{{Guest Name}}/g, name);
    resolve(text);
  });
}

module.exports = {
  buildText
}

代码.test.js

const Code = require('./code');
const { Message } = require('./message');

describe("funcs", () => {
  it("buildText", async () => {
    const mock = jest.spyOn(Message, 'findOne');  // spy on Message.findOne()
    mock.mockImplementation(() => Promise.resolve({
      message: 'the message'
    }));  // replace the implementation

    let listing = {
      _id: "1324",
      pricingEnabled: true,
      listingFound: true,
      hideListing: null
    };
    let messageRule = {
      _id: "3452345",
      minNights: 1,
      reviewEnabled: false,
      disableMessageAfterReview: false,
      message: 'test',
      lastMinuteMessage: 'test2'
    };
    let reservation = {
      _id: "63452345",
      hasLeftReview: true,
      hasIssues: false
    };
    let isReview = false;
    let isLastMinuteMessage = false;
    let response = await Code.buildText(listing, messageRule, reservation, isReview, isLastMinuteMessage);
    expect(response).toMatchSnapshot();

    mock.mockRestore();  // restore Message.findOne()
  });
});

message.js(示例的虚拟模型)

const mongoose = require('mongoose');

exports.Message = mongoose.model('Message', new mongoose.Schema({ }));

推荐阅读