【问题标题】:Jest toMatchObject with MongoDB confusingJest toMatchObject 与 MongoDB 混淆
【发布时间】:2020-07-27 18:51:16
【问题描述】:

我对我的猫鼬模型进行了测试,虽然一个模型的测试运行完全正常,但另一个基本上是复制品的测试 - 不起作用。老实说,我不明白这个问题。我试图删除一些属性或添加硬编码值以真正匹配 100% - 但不知何故我总是得到类似的错误。

错误。让我发疯的是我试图删除/添加“_id”和“createdOn”字段,但至少“_id”总是出现在错误中。如上所述,在另一个模型中,测试不会抱怨“_id”,因为我没有在那里验证它......我只是不明白。

insert › Should save a channel

expect(received).toMatchObject(expected)

- Expected  - 1
+ Received  + 2

@@ -1,8 +1,9 @@
  Object {
+   "_id": "5e962f1dc133d8b92891ddaf",
    "createdBy": "5e962f1dc133d8b92891ddae",
-   "createdOn": Anything,
+   "createdOn": 2020-04-14T21:46:05.907Z,
    "hasAcceptedLegal": false,
    "isActive": true,
    "isPublic": false,
    "members": Array [
      "5e962f1dc133d8b92891ddae",

  48 |     expect(spy).toHaveBeenCalled();
  49 | 
> 50 |     expect(channel).toMatchObject({
     |                     ^
  51 |       name: mockName,
  52 |       createdBy: mockCreatedById,
  53 |       createdOn: expect.anything(),

  at Object.it (test/model/channel.model.test.ts:50:21)

各自的模型

import mongoose, { Schema, Document } from "mongoose";
import { IUser } from "./user.model";

export interface IChannel extends Document {
  name: string;
  createdBy: IUser["id"];
  createdOn: Date;
  isActive: boolean;
  isPublic: boolean;
  hasAcceptedLegal: boolean;
  members: [IUser["id"]];
}

const ChannelSchema: Schema = new Schema({
  name: { type: String, required: true },
  createdBy: {
    type: Schema.Types.ObjectId,
    ref: "User",
    required: true,
  },
  createdOn: { type: Date },
  isActive: { type: Boolean, default: true },
  isPublic: { type: Boolean, default: false },
  hasAcceptedLegal: { type: Boolean, default: false },
  members: [
    {
      type: Schema.Types.ObjectId,
      ref: "User",
      required: true,
    },
  ],
});

export default mongoose.model<IChannel>("Channel", ChannelSchema);

测试:

it("Should save a channel", async () => {
    expect.assertions(2);
    let mockName = Faker.company.companyName();
    let mockCreatedById = Types.ObjectId();
    let mockCreatedOn = Date.now();

    const channel: IChannel = new Channel({
      name: mockName,
      createdBy: mockCreatedById,
      createdOn: mockCreatedOn,
      members: [mockCreatedById],
    });
    const spy = jest.spyOn(channel, "save");
    channel.save();

    expect(spy).toHaveBeenCalled();

    expect(channel).toMatchObject({
      name: mockName,
      createdBy: mockCreatedById,
      createdOn: expect.anything(),
      isActive: true,
      isPublic: false,
      hasAcceptedLegal: false,
      members: [mockCreatedById],
    });
  });

【问题讨论】:

  • 如果将.toMatchObject 替换为.toEqual 会出现什么错误?
  • 我认为 .toEqual 也有类似的问题,因为日期的格式有点奇怪。它不是字符串,也不是日期……我认为这才是真正导致问题的原因。请参阅下面的解决方法。

标签: mongodb typescript mongoose jestjs


【解决方案1】:

仅供参考,我发现了某事。返回的 mongoose 对象应该用“.toJSON()”转换,然后它可以工作,但即使这样,“createdOn”字段也有问题,因为它似乎是格式化的日期或某事。像这样(没有字符串,缺少括号)。 我现在终于做了以下事情,现在它可以工作了:

it("Should save a channel (required+defaults)", async () => {
    expect.assertions(2);
    let mockName = Faker.company.companyName();
    let mockCreatedById = Types.ObjectId();
    let mockCreatedOn = new Date();

    const channel: IChannel = new Channel({
      name: mockName,
      createdBy: mockCreatedById,
      createdOn: mockCreatedOn,
      members: [mockCreatedById],
    });
    const spy = jest.spyOn(channel, "save");
    channel.save();

    expect(spy).toHaveBeenCalled();

    expect(channel.toJSON()).toMatchObject({
      _id: expect.anything(),
      name: mockName,
      createdBy: mockCreatedById,
      createdOn: expect.anything(),
      isActive: true,
      isPublic: false,
      hasAcceptedLegal: false,
      members: expect.arrayContaining([mockCreatedById]),
    });
  });

【讨论】:

  • 当使用.toMatchObject 时,它只会匹配您有描述的属性,因此expect.anything() 将与删除描述具有相同的结果
猜你喜欢
  • 2019-04-21
  • 1970-01-01
  • 2013-08-19
  • 2015-06-25
  • 2014-07-09
  • 1970-01-01
  • 2016-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多