I've been trying to test mongoose models using AVA.
As validation errors tend not to be type errors I tried various things and came to this working way:
The Model
// Model
// Require Mongoose
import mongoose from "mongoose";
// Define a schema
const Schema = mongoose.Schema;
/**
* Story Point Report Schema
* The timestamps used in this way create updatedAt and createdAt automatically
*/
const storyPointsSchema = new Schema({
firstName: {
required: true,
type: String,
maxLength: 100
},
lastName: {
required: true,
type: String,
maxLength: 100
},
team: {
required: true,
type: String}
,
storyPoints: {
type: Number
},
sprint: {
name: {
required: true,
type: String
},
startDate: {
required: true,
type: Date,
},
endDate: {
required: true,
type: Date,
}
}
}, {timestamps: true });
storyPointsSchema.pre('save', function(next){
this.spintStartDate = Date.now();
this.sprintEndDate = Date.now() + 14;
})
/**
* Calculate Full Name
* Virtual for ticket assignee's full name
*/
storyPointsSchema.virtual('name').get(() => {
let fullname = ""
if (this.firstName && this.lastName) {
fullname = `${this.firstName}, ${this.lastName}`
}
return fullname
})
function convertDateToReadableFormat(Date) {
return DateTime.formJSDate(Date).toLocaleString(DateTime.DATE_MED);
}
storyPointsSchema.virtual('prety_dates').get(() => {
return {
sprintStartDateF: convertDateToReadableFormat(this.spintStartDate),
sprintEndDateF: convertDateToReadableFormat(this.spintEndDate),
updatedAtF: convertDateToReadableFormat(this.updatedAt)
}
})
export const StoryPoints = mongoose.model('StoryPoints', storyPointsSchema)
The AVA unit test that currently passes
import test from 'ava';
import {StoryPoints} from '../../models/story_points.js';
let storyPointsSchema = null;
test.before(t => {
storyPointsSchema = new StoryPoints();
storyPointsSchema.sprint.endDate = Date.now();
storyPointsSchema.sprint.startDate = Date.now();
storyPointsSchema.sprint.name = "Story Points Test";
storyPointsSchema.team = "The Testers";
storyPointsSchema.firstName = "Joe";
storyPointsSchema.lastName = "Smoe";
});
test("Undefined first name should have error 'Path `firstName` is required.'", async t => {
const sPs = new StoryPoints();
const except = async () => {
throw new Error(await sPs.save());
}
try {
await except();
} catch(e) {
t.deepEqual(
'Path `firstName` is required.',
e.errors.firstName.properties.message
)
}
});
I hope this helps someone!
If you have a better way to do this then please share; otherwise have a great day!
I did try t.throwsAsync() however it wasn’t catching the Mongoose validation errors which is how I came to this solution.