typescript - Jest toMatchObject med MongoDB förvirrande
Jag har ett test på min mongoose-modell och medan en modells tester körs helt felfritt, fungerar en annan som i princip är en kopia - inte. Och ärligt talat förstår jag inte problemet. Jag försökte ta bort några av egenskaperna eller lägga till hårdkodade värden för att verkligen matcha 100% exakt - men på något sätt får jag alltid ett liknande fel.
Felet. Vad som driver mig galen är att jag försökte ta bort/lägga till fältet "_id" och "createdOn", men åtminstone "_id" dyker alltid upp i felet. Som sagt ovan, i en annan modell klagar testet inte på "_id" eftersom jag inte validerar det där... Jag fattar det bara inte.
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)
Den respektive modellen
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);
Testet:
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],
});
});
Svar #1
bara som referens, jag hittade något att det returnerade mongoose-objektet bör konverteras med ".toJSON()" och sedan fungerar det, men även då hade det problem med fältet "createdOn" eftersom det verkar vara ett formaterat datum eller något liknande (inte en sträng, parentes saknas). Vad jag slutligen gjorde nu var följande och nu fungerar det:
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]),
});
});
