Det kan være en udfordring at teste Mongoose-modeller, fordi du skal skrive test, der ikke forstyrrer din egentlige database. MongoDB-hukommelsesserverpakken tilbyder en ligetil løsning. Det lader dig gemme dine testdata i applikationshukommelsen.
I denne tutorial vil du oprette en simpel Mongoose-model og skrive test ved hjælp af Jest og MongoDB-hukommelsesserveren.
Hvad er MongoDB Memory Server?
Den sidste ting, du ønsker, er at gemme falske data i din rigtige database, hvilket kan ske, hvis du opretter forbindelse til det under test. I stedet kan du vælge at bruge en separat lokal MongoDB-instans til at gemme dine data. Selvom dette virker, er det umuligt, hvis dine test kører på skyen. Desuden kan det blive dyrt at forbinde og forespørge efter en rigtig database under hver test.
MongoDB hukommelsesserver, dog spinner en rigtig MongoDB-server op og giver dig mulighed for at gemme testdataene i hukommelsen. Dette gør det hurtigere end at bruge en lokal MongoDB-database, da data ikke skrives på en fysisk disk.
Oprettelse af Mongoose-modellen
Mongoose-modeller giver en grænseflade til grænseflader med MongoDB-databasen. For at oprette dem skal du kompilere dem fra et Mongoose-skema, som definerer din MongoDB-datamodel. Denne øvelse vil bruge et skema til et opgavedokument. Den vil indeholde titlen og udfyldte felter.
Kør følgende kommando i terminalen for at oprette en ny mappe og navigere til den.
mkdir mongoose-model-test
cd mongoose-model-test
Initialiser npm med følgende kommando:
npm init -y
Det -y flag instruerer npm om at generere en package.json-fil med standardværdier.
Udfør denne kommando for at installere mangust pakke:
npm installere mangust
Opret en ny fil kaldet todo.model.js og definer opgaveskemaet:
konst mangust = kræve("mangust")
konst { Skema } = mangust
konst TodoSchema = ny Skema({
vare: {
type: Snor,
påkrævet: rigtigt
},
gennemført: {
type: Boolean,
påkrævet: rigtigt
}
})
I slutningen af denne fil skal du oprette og eksportere todo-modellen:
modul.eksport = mongoose.model("Todo", TodoSchema)
Planlægning af prøverne
Når du skriver test, vil du på forhånd planlægge, hvad du skal teste. Dette sikrer, at du tester al din models funktionalitet.
Ud fra Mongoose-modellen, vi oprettede, skal opgaven indeholde et element af typen String og et udfyldt felt af typen Boolean. Begge disse felter er obligatoriske. Det betyder, at vores test som minimum skal sikre:
- Gyldige elementer er gemt i databasen.
- Elementer uden obligatoriske felter gemmes ikke.
- Elementer med felter af ugyldig type gemmes ikke.
Vi vil skrive disse tests i én testblok, da de er relaterede. I Jest definerer du denne testblok ved hjælp af beskrive fungere. For eksempel:
beskrive('Todo model test', () => {
// Dine tests går her
}
Opsætning af databasen
For at konfigurere en MongoDB-hukommelsesserver skal du oprette en ny Mongo-hukommelsesserverinstans og oprette forbindelse til Mongoose. Du vil også oprette funktioner, der vil være ansvarlige for at droppe alle samlingerne i databasen og afbryde forbindelsen til Mongo-hukommelsesserverinstansen.
Kør følgende kommando for at installere mongodb-memory-server.
npm installere mongodb-hukommelse-server
Opret en ny fil kaldet setuptestdb.js og importer mongoose og mongodb-memory-server.
konst mangust = kræve("mangust");
konst { MongoMemoryServer } = kræve("mongodb-hukommelsesserver");
Opret derefter en connectDB() funktion. Denne funktion opretter en ny Mongo-hukommelsesserverinstans og forbinder til Mongoose. Du vil køre det før alle testene for at oprette forbindelse til testdatabasen.
lade mongo = nul;
konst connectDB = asynkron () => {
mongo = vente MongoMemoryServer.create();
konst uri = mongo.getUri();
vente mongoose.connect (uri, {
useNewUrlParser: rigtigt,
brug UnifiedTopology: rigtigt,
});
};
Opret en dropDB() funktion ved at tilføje følgende kode. Denne funktion dropper databasen, lukker Mongoose-forbindelsen og stopper Mongo-hukommelsesserverforekomsten. Du vil køre denne funktion, når alle testene er færdige.
konst dropDB = asynkron () => {
if (mongo) {
ventemangust.forbindelse.dropDatabase();
ventemangust.forbindelse.tæt();
vente mongo.stop();
}
};
Den sidste funktion, du vil oprette, hedder dropCollections(). Det dropper alle de oprettede Mongoose-samlinger. Du vil køre det efter hver test.
konst dropCollections = asynkron () => {
if (mongo) {
konst samlinger = vente mongoose.connection.db.collections();
til (lade kollektion af samlinger) {
vente collection.remove();
}
}
};
Til sidst eksporter du funktionerne conenctDB(), dropDB() og dropCollections().
modul.eksport = { connectDB, dropDB, dropCollections}
At skrive prøverne
Som nævnt vil du bruge Jest til at skrive testene. Kør følgende kommando for at installere jest.
npm installere spøg
I den package.json fil, konfigurer spøg. Erstat din eksisterende "scripts"-blok med følgende:
"scripts": {
"prøve": "jest --runInBand --detectOpenHandles"
},
"spøg": {
"testmiljø": "node"
},
Opret en ny fil kaldet todo.model.test.js og importer mongoose-biblioteket, todo-modellen og conenctDB(), dropDB() og dropCollections()-funktionerne:
konst mangust = kræve("mangust");
konst { connectDB, dropDB, dropCollections } = kræve("./setupdb");
konst Todo = kræve("./todo.model");
Du skal køre funktionen connectDB() før alle testene kører. Med Jest kan du bruge beforeAll() metoden.
Du skal også køre oprydningsfunktioner. Efter hver test skal du køre dropCollections()-funktionen og dropDB()-funktionen efter alle testene. Du behøver ikke at gøre dette manuelt og kan bruge afterEach() og afterAll() metoderne fra Jest.
Tilføj følgende kode til filen todo.model.test.js for at konfigurere og rydde op i databasen.
førAlle(asynkron () => {
vente connectDB();
});trods alt(asynkron () => {
vente dropDB();
});
efterHver(asynkron () => {
vente dropCollections();
});
Du er nu klar til at oprette testene.
Den første test vil kontrollere, om opgaveelementet blev indsat i databasen. Det vil kontrollere, om objekt-id'et er til stede i den oprettede til, og om dataene deri matcher den, du sendte til databasen.
Opret en beskrivelsesblok og tilføj følgende kode.
beskrive("Todo model", () => {
det("skal oprette et opgaveelement med succes", asynkron () => {
lade validTodo = {
vare: "Tag opvasken",
afsluttet: falsk,
};
konst newTodo = vente Todo (validTodo);
vente newTodo.save();
forventer(newTodo._id).at blive defineret();
forventer(newTodo.vare).at være(validTodo.vare);
forventer(newTodo.fuldført).at være(validTodo.fuldført);
});
});
Dette opretter et nyt dokument i databasen indeholdende dataene i variablen validTodo. Det returnerede objekt valideres derefter mod de forventede værdier. For at denne test skal bestå, skal den returnerede værdi have et objekt-id. Værdierne i elementet og de udfyldte felter skal også matche værdierne i validTodo-objektet.
Udover at teste den normale use case, skal du også teste en mislykket use case. Fra de test, vi planlagde, skal du teste mongoose-modellen med et todo-objekt, med et manglende obligatorisk felt og et med en forkert type.
Tilføj en anden test til den samme beskrivelsesblok, som følger:
det("skulle mislykkes for todo-emne uden obligatoriske felter", asynkron () => {
lade invalidTodo = {
vare: "Tag opvasken",
};
prøve {
konst newTodo = ny Todo (ugyldigTodo);
vente newTodo.save();
} fangst (fejl) {
forventer(fejl).toBeInstanceOf(mangust.Fejl.ValidationError);
forventer(fejl.fejl.fuldført).at blive defineret();
}
});
Todo mongoose modellen forventer både varen og udfyldte felter. Det burde give en fejl, hvis du forsøger at gemme en opgave uden et af disse felter. Denne test bruger try...catch-blokken til at fange den kastede fejl. Testen forventer, at fejlene er en mongoose-valideringsfejl og stammer fra det manglende udfyldte felt.
For at teste, om modellen kaster en fejl, hvis du bruger værdier af den forkerte type, skal du tilføje følgende kode til describe-blokken.
det("skulle mislykkes for todo-emne med felter af forkert type", asynkron () => {
lade invalidTodo = {
vare: "Tag opvasken",
afsluttet: "Falsk"
};
prøve {
konst newTodo = ny Todo (ugyldigTodo);
vente newTodo.save();
} fangst (fejl) {
forventer(fejl).toBeInstanceOf(mangust.Fejl.ValidationError);
forventer(fejl.fejl.fuldført).at blive defineret();
}
});
Bemærk, at værdien af det udfyldte felt er en streng i stedet for en boolesk værdi. Testen forventer, at der opstår en valideringsfejl, da modellen forventer en boolsk værdi.
MongoMemoryServer og Jest udgør et fantastisk team
Mongo-memory-server npm-pakken giver en nem løsning til at teste Mongoose-modeller. Du kan gemme dummy-data i hukommelsen uden at røre ved din applikations database.
Du kan bruge MongoMemoryServer med Jest til at skrive test for Mongoose-modeller. Bemærk, at den ikke dækker alle de mulige tests, du kan skrive for dine modeller. Disse test vil afhænge af dit skema.