Può essere una sfida testare i modelli Mongoose perché è necessario scrivere test che non interferiscano con il database effettivo. Il pacchetto del server di memoria MongoDB offre una soluzione semplice. Ti consente di memorizzare i dati del test nella memoria dell'applicazione.

In questo tutorial creerai un semplice modello Mongoose e scriverai test usando Jest e il server di memoria MongoDB.

Che cos'è il server di memoria MongoDB?

L'ultima cosa che vuoi è salvare dati falsi nel tuo database reale, cosa che potrebbe accadere se ti connetti ad esso durante i test. Invece, puoi scegliere di utilizzare un'istanza MongoDB locale separata per archiviare i tuoi dati. Sebbene funzioni, non è fattibile se i tuoi test vengono eseguiti sul cloud. Inoltre, la connessione e l'interrogazione di un database reale durante ogni test può diventare costoso.

Server di memoria MongoDB, tuttavia, avvia un vero server MongoDB e ti consente di archiviare i dati di test in memoria. Ciò lo rende più veloce rispetto all'utilizzo di un database MongoDB locale poiché i dati non vengono scritti su un disco fisico.

instagram viewer

Creazione del modello della mangusta

I modelli Mongoose forniscono un'interfaccia per l'interfaccia con il database MongoDB. Per crearli, devi compilarli da uno schema Mongoose, che definisce il tuo modello di dati MongoDB. Questo tutorial utilizzerà uno schema per un documento da fare. Conterrà il titolo e i campi compilati.

Eseguire il comando seguente nel terminale per creare una nuova cartella e accedervi.

mkdir mongoose-model-test
CD mangusta-modello-test

Inizializzare npm con il seguente comando:

npm init -y

Il -y flag indica a npm di generare un file package.json con valori predefiniti.

Esegui questo comando per installare il file mangusta pacchetto:

npm installare mangusta

Crea un nuovo file chiamato todo.model.js e definire lo schema da fare:

cost mangusta = richiedere("mangusta")
cost { Schema } = mangusta
cost Schema Todo = nuovo Schema({
elemento: {
genere: Corda,
necessario: VERO
},
completato: {
genere: booleano,
necessario: VERO
}
})

Alla fine di questo file, crea ed esporta il modello di cose da fare:

modulo.esportazioni = mongoose.model("Todo", Schema Todo)

Pianificazione dei test

Quando scrivi i test, vuoi pianificare in anticipo ciò che testerai. Ciò ti assicura di testare tutte le funzionalità del tuo modello.

Dal modello Mongoose che abbiamo creato, la cosa da fare dovrebbe contenere un elemento di tipo String e un campo completato di tipo Boolean. Entrambi questi campi sono obbligatori. Ciò significa che, come minimo, il nostro test dovrebbe garantire:

  • Gli elementi validi vengono salvati correttamente nel database.
  • Gli articoli senza campi obbligatori non vengono salvati.
  • Gli elementi con campi di tipo non valido non vengono salvati.

Scriveremo questi test in un blocco di test poiché sono correlati. In Jest, definisci questo blocco di test usando il descrivere funzione. Per esempio:

descrivere('Test modello Todo', () => {
// I tuoi test vanno qui
}

Configurazione del database

Per configurare un server di memoria MongoDB, creerai una nuova istanza del server di memoria Mongo e ti connetterai a Mongoose. Creerai anche funzioni che saranno responsabili dell'eliminazione di tutte le raccolte nel database e della disconnessione dall'istanza del server di memoria Mongo.

Esegui il comando seguente per installare server di memoria mongodb.

npm installare mongodb-memoria-server

Crea un nuovo file chiamato setuptestdb.js e importa mongoose e mongodb-memory-server.

cost mangusta = richiedere("mangusta");
cost {MongoMemoryServer} = richiedere("server di memoria mongodb");

Quindi, crea una funzione connectDB(). Questa funzione crea una nuova istanza del server di memoria Mongo e si connette a Mongoose. Lo eseguirai prima di tutti i test per connetterti al database dei test.

permettere mongo = nullo;

cost connettiDB = asincrono () => {
mongo = aspettare MongoMemoryServer.create();
cost uri = mongo.getUri();

aspettare mongoose.connect (uri, {
useNewUrlParser: VERO,
usaUnifiedTopology: VERO,
});
};

Crea una funzione dropDB() aggiungendo il codice seguente. Questa funzione elimina il database, chiude la connessione Mongoose e arresta l'istanza del server di memoria Mongo. Eseguirai questa funzione al termine di tutti i test.

cost dropDB = asincrono () => {
se (mongo) {
aspettaremangusta.connessione.dropDatabase();
aspettaremangusta.connessione.chiudere();
aspettare mongo.stop();
}
};

L'ultima funzione che creerai si chiama dropCollections(). Rilascia tutte le raccolte Mongoose create. Lo eseguirai dopo ogni test.

cost dropCollections = asincrono () => {
se (mongo) {
cost collezioni = aspettare mongoose.connection.db.collections();
per (permettere collezione di collezioni) {
aspettare raccolta.rimuovi();
}
}
};

Infine, esporta le funzioni conenctDB(), dropDB() e dropCollections().

modulo.esportazioni = {connectDB, dropDB, dropCollections}

Scrivere le prove

Come accennato, utilizzerai Jest per scrivere i test. Esegui il comando seguente per installare jest.

npm installare scherzo

Nel pacchetto.json file, configura jest. Sostituisci il tuo blocco "script" esistente con il seguente:

"script": {
"test": "jest --runInBand --detectOpenHandles"
},
"scherzo": {
"ambiente di test": "nodo"
},

Crea un nuovo file chiamato todo.model.test.js e importa la libreria mongoose, il modello todo e le funzioni conenctDB(), dropDB() e dropCollections():

cost mangusta = richiedere("mangusta");
cost {connectDB, dropDB, dropCollections} = richiedere(./setupdb");
cost Todo = richiedere("./todo.model");

È necessario eseguire la funzione connectDB() prima dell'esecuzione di tutti i test. Con Jest, puoi usare il metodo beforeAll().

È inoltre necessario eseguire le funzioni di pulizia. Dopo ogni test, eseguire la funzione dropCollections() e la funzione dropDB() dopo tutti i test. Non è necessario farlo manualmente e puoi utilizzare i metodi afterEach() e afterAll() di Jest.

Aggiungi il codice seguente al file todo.model.test.js per configurare e ripulire il database.

prima di tutto(asincrono () => {
aspettare connectDB();
});

Dopotutto(asincrono () => {
aspettare dropDB();
});

dopo ogni(asincrono () => {
aspettare dropCollections();
});

Ora sei pronto per creare i test.

Il primo test verificherà se l'elemento da fare è stato inserito correttamente nel database. Verificherà se l'ID oggetto è presente nell'oggetto creato e se i dati in esso contenuti corrispondono a quelli che hai inviato al database.

Crea un blocco di descrizione e aggiungi il codice seguente.

descrivere("Modello Todo", () => {
esso("dovrebbe creare una cosa da fare con successo", asincrono () => {
permettere validoTodo = {
elemento: "Lavare i piatti",
completato: falso,
};
cost nuovoTodo = aspettare Todo (validTodo);
aspettare newTodo.save();
aspettare(nuovoTodo._id).da definire();
aspettare(nuovoTodo.elemento).essere(validoTodo.elemento);
aspettare(nuovoTodo.completato).essere(validoTodo.completato);
});
});

Questo crea un nuovo documento nel database contenente i dati nella variabile validTodo. L'oggetto restituito viene quindi convalidato rispetto ai valori previsti. Affinché questo test superi, il valore restituito deve avere un ID oggetto. Inoltre, i valori nell'elemento e nei campi completati devono corrispondere a quelli nell'oggetto validTodo.

Oltre a testare il normale caso d'uso, devi anche testare un caso d'uso non riuscito. Dai test che abbiamo pianificato, è necessario testare il modello della mangusta con un oggetto da fare, con un campo obbligatorio mancante e uno di tipo errato.

Aggiungi un secondo test allo stesso blocco di descrizione, come segue:

 esso("dovrebbe fallire per l'elemento da fare senza campi obbligatori", asincrono () => {
permettere invalidTodo = {
elemento: "Lavare i piatti",
};
Tentativo {
cost nuovoTodo = nuovo Todo (invalidTodo);
aspettare newTodo.save();
} presa (errore) {
aspettare(errore).toBeInstanceOf(mangusta.Errore.Errore di convalida);
aspettare(errore.errori.completato).da definire();
}
});

Il modello della mangusta Todo prevede sia l'articolo che i campi completati. Dovrebbe generare un errore se provi a salvare una cosa da fare senza uno di questi campi. Questo test usa il blocco try...catch per catturare l'errore generato. Il test prevede che gli errori siano un errore di convalida mangusta e derivino dal campo completato mancante.

Per verificare se il modello genera un errore se si utilizzano valori di tipo errato, aggiungere il codice seguente al blocco di descrizione.

 esso("dovrebbe fallire per l'elemento da fare con campi di tipo errato", asincrono () => {
permettere invalidTodo = {
elemento: "Lavare i piatti",
completato: "Falso"
};
Tentativo {
cost nuovoTodo = nuovo Todo (invalidTodo);
aspettare newTodo.save();
} presa (errore) {
aspettare(errore).toBeInstanceOf(mangusta.Errore.Errore di convalida);
aspettare(errore.errori.completato).da definire();
}
});

Nota che il valore del campo completato è una stringa anziché un booleano. Il test prevede che venga generato un errore di convalida poiché il modello prevede un valore booleano.

MongoMemoryServer e Jest formano una grande squadra

Il pacchetto mongo-memory-server npm fornisce una soluzione semplice per testare i modelli Mongoose. Puoi archiviare dati fittizi in memoria senza toccare il database della tua applicazione.

È possibile utilizzare MongoMemoryServer con Jest per scrivere test per i modelli Mongoose. Nota che non copre tutti i possibili test che puoi scrivere per i tuoi modelli. Questi test dipenderanno dal tuo schema.