Vorrei interrompere il metodo save
disponibile per i modelli Mongoose. Ecco un modello di esempio:Stubing del metodo di salvataggio mangusta su un modello
/* model.js */
var mongoose = require('mongoose');
var userSchema = mongoose.Schema({
username: {
type: String,
required: true
}
});
var User = mongoose.model('User', userSchema);
module.exports = User;
ho qualche funzione di supporto che chiamerà il metodo save
.
/* utils.js */
var User = require('./model');
module.exports = function(req, res) {
var username = req.body.username;
var user = new User({ username: username });
user.save(function(err) {
if (err) return res.end();
return res.sendStatus(201);
});
};
vorrei controllare che user.save
è chiamato dentro la mia funzione di supporto utilizzando un test di unità.
/* test.js */
var mongoose = require('mongoose');
var createUser = require('./utils');
var userModel = require('./model');
it('should do what...', function(done) {
var req = { username: 'Andrew' };
var res = { sendStatus: sinon.stub() };
var saveStub = sinon.stub(mongoose.Model.prototype, 'save');
saveStub.yields(null);
createUser(req, res);
// because `save` is asynchronous, it has proven necessary to place the
// expectations inside a setTimeout to run in the next turn of the event loop
setTimeout(function() {
expect(saveStub.called).to.equal(true);
expect(res.sendStatus.called).to.equal(true);
done();
}, 0)
});
ho scoperto var saveStub = sinon.stub(mongoose.Model.prototype, 'save')
da here.
Tutto va bene a meno che non provi ad aggiungere qualcosa al mio saveStub
, ad es. con saveStub.yields(null)
. Se avessi voluto simulare un errore di essere passato al save
callback con saveStub.yields('mock error')
, ottengo questo errore:
TypeError: Attempted to wrap undefined property undefined as function
Lo stack trace è del tutto inutile.
La ricerca che ho fatto
ho tentato di refactoring il mio modello per ottenere l'accesso al modello di utente di base, come raccomandato here. Ciò ha prodotto lo stesso errore per me. Qui è stato il mio codice per quel tentativo:
/* in model.js... */
var UserSchema = mongoose.model('User');
User._model = new UserSchema();
/* in test.js... */
var saveStub = sinon.stub(userModel._model, 'save');
ho scoperto che this solution non ha funzionato per me a tutti. Forse perché sto configurando il mio modello utente in un modo diverso?
Ho provato anche Mockery a seguito di this guide e this one, ma quello era molto più di quello che pensavo dovesse essere necessario, e mi ha fatto dubitare del valore di passare il tempo a isolare il db.
La mia impressione è che tutto ciò abbia a che fare con il misterioso sistema di attrezzi Mongoose save
. Ho letto qualcosa a riguardo usando npm hooks
, che rende il metodo save
una cosa scivolosa da stubare.
Ho anche sentito parlare di mockgoose, anche se non ho ancora provato questa soluzione. Qualcuno ha avuto successo con quella strategia? [MODIFICA: risulta che mockgoose fornisce un database in memoria per facilitare l'installazione/rimozione, ma non risolve il problema dello stub.]
Qualsiasi opinione su come risolvere questo problema sarebbe molto apprezzata.
Ha funzionato per me! Grazie mille per la condivisione! <3 –