I'm writing unit tests for an API that uses MongoDB, with mongoose being used to access the database.
I have a model file which defines and exports a mongoose model:
const { Schema, model } = require('mongoose');
const TravelSchema = new Schema({
staffFirstName: {
type: String,
required: true,
},
staffLastName: {
type: String,
required: false,
},
kmTravelled: {
type: Number,
required: true,
},
});
module.exports = model('travel', TravelSchema);
I then have a method that takes a req and res, constructs an object out of the attributes of the req.body, then saves it to the database:
const TravelSchema = require('../models/travel_usage');
exports.submitTravelUsage = async function (req, res) {
try {
var data = {
staffFirstName: req.body.staffFirstName,
staffLastName: req.body.staffLastName,
kmTravelled: req.body.kmTravelled,
}
var travelUsage = new TravelUsage(data);
travelUsage.save();
return res.status(201).json(data);
}catch(error){
console.log(error.message);
return res.status(400).json({message: error.message});
}
My test file for the backend method looks something like:
const request = require('supertest');
const app = require('../src/app');
const sinon = require('sinon');
const assert = require('assert').strict;
const TravelSchema = require('../models/travel_usage');
describe('POST /travelUsage - returns 201', function () {
it('responds with 201 created - basic POST body', function (done) {
this.timeout(7500);
var save = sinon.spy(TravelSchema, 'save');
request(app)
.post('/travelUsage')
.set('Content-Type', 'application/json')
.send(travelUsageData)
.then(function (response) {
assert.equal(response.status, 201);
sinon.assert.calledOnce(save);
done();
})
.catch(err => done(err));
})
})
But when the test is run an error is thrown saying TypeError: Cannot stub non-existent property save. It seems that the model object exported by the model file doesn't contain the save() method, but when a new model is created with data it gains the save() method, so is there a better way to spy on the save method being called in the submitTravelUsage method?