Het kan een uitdaging zijn om Mongoose-modellen te testen, omdat je tests moet schrijven die niet interfereren met je eigenlijke database. Het MongoDB-geheugenserverpakket biedt een eenvoudige oplossing. Hiermee kunt u uw testgegevens opslaan in het applicatiegeheugen.

In deze zelfstudie maakt u een eenvoudig Mongoose-model en schrijft u tests met Jest en de MongoDB-geheugenserver.

Wat is MongoDB-geheugenserver?

Het laatste dat u wilt, is nepgegevens opslaan in uw echte database, wat kan gebeuren als u er tijdens het testen verbinding mee maakt. In plaats daarvan kunt u ervoor kiezen om een ​​afzonderlijke lokale MongoDB-instantie te gebruiken om uw gegevens op te slaan. Hoewel dit werkt, is het onhaalbaar als uw tests in de cloud worden uitgevoerd. Bovendien kan het verbinden en opvragen van een echte database tijdens elke test duur worden.

MongoDB-geheugenserver, zet echter een echte MongoDB-server op en stelt u in staat de testgegevens in het geheugen op te slaan. Dit maakt het sneller dan het gebruik van een lokale MongoDB-database, omdat gegevens niet op een fysieke schijf worden geschreven.

Het mangoestmodel maken

Mongoose-modellen bieden een interface voor interfacing met de MongoDB-database. Om ze te maken, moet je ze compileren vanuit een Mongoose-schema, die uw MongoDB-gegevensmodel definieert. In deze zelfstudie wordt een schema voor een taakdocument gebruikt. Het bevat de titel en de ingevulde velden.

Voer de volgende opdracht uit in de terminal om een ​​nieuwe map te maken en navigeer ernaar.

mkdir mangoest-model-test
CD mangoest-model-test

Initialiseer npm met het volgende commando:

npm init -y

De -y flag instrueert npm om een ​​package.json-bestand met standaardwaarden te genereren.

Voer deze opdracht uit om de. te installeren mangoest pakket:

npm installeren mangoest

Maak een nieuw bestand met de naam todo.model.js en definieer het takenschema:

const mangoest = vereisen("mangoest")
const { Schema } = mangoest
const TodoSchema = nieuwe Schema({
artikel: {
type: Snaar,
verplicht: WAAR
},
voltooid: {
type: Booleaans,
verplicht: WAAR
}
})

Maak en exporteer aan het einde van dit bestand het todo-model:

module.exporteert = mangoest.model("Todo", TodoSchema)

De tests plannen

Bij het schrijven van toetsen wil je van tevoren plannen wat je gaat testen. Dit zorgt ervoor dat u alle functionaliteit van uw model test.

Van het Mongoose-model dat we hebben gemaakt, moet de taak een item van het type String en een ingevuld veld van het type Boolean bevatten. Beide velden zijn verplicht. Dit betekent dat onze test minimaal moet zorgen voor:

  • Geldige items zijn succesvol opgeslagen in de database.
  • Artikelen zonder verplichte velden worden niet opgeslagen.
  • Items met velden van een ongeldig type worden niet opgeslagen.

We zullen deze tests in één testblok schrijven omdat ze gerelateerd zijn. In Jest definieert u dit testblok met behulp van de beschrijven functie. Bijvoorbeeld:

beschrijven('Todo-modeltest', () => {
// Je tests gaan hier
}

De database instellen

Om een ​​MongoDB-geheugenserver in te stellen, maakt u een nieuwe Mongo-geheugenserverinstantie en maakt u verbinding met Mongoose. U zult ook functies maken die verantwoordelijk zijn voor het verwijderen van alle collecties in de database en het loskoppelen van de Mongo-geheugenserverinstantie.

Voer de volgende opdracht uit om te installeren: mongodb-geheugenserver.

npm installeren mongob-geheugen-server

Maak een nieuw bestand met de naam setuptestdb.js en importeer mangoest en mongodb-memory-server.

const mangoest = vereisen("mangoest");
const { MongoMemoryServer } = vereisen("mongodb-geheugenserver");

Maak vervolgens een connectDB()-functie. Deze functie maakt een nieuwe Mongo-geheugenserverinstantie en maakt verbinding met Mongoose. U voert het uit vóór alle tests om verbinding te maken met de testdatabase.

laten mongo = nul;

const connectDB = asynchrone () => {
mongo = wachten MongoMemoryServer.create();
const uri = mongo.getUri();

wachten mangoest.connect (uri, {
useNewUrlParser: WAAR,
useUnifiedTopology: WAAR,
});
};

Maak een dropDB()-functie door de volgende code toe te voegen. Deze functie verwijdert de database, sluit de Mongoose-verbinding en stopt de Mongo-geheugenserverinstantie. U voert deze functie uit nadat alle tests zijn uitgevoerd.

const dropDB = asynchrone () => {
als (mongo) {
wachtenmangoest.verbinding.dropDatabase();
wachtenmangoest.verbinding.dichtbij();
wachten mongo.stop();
}
};

De laatste functie die je gaat maken heet dropCollections(). Het laat alle gemaakte Mongoose-collecties vallen. U voert het na elke test uit.

const dropCollections = asynchrone () => {
als (mongo) {
const verzamelingen = wachten mangoest.connection.db.collections();
voor (laten verzameling van collecties) {
wachten verzameling.verwijder();
}
}
};

Exporteer ten slotte de functies conenctDB(), dropDB() en dropCollections().

module.exporteert = {connectDB, dropDB, dropCollections}

De tests schrijven

Zoals gezegd, gebruik je Jest om de tests te schrijven. Voer de volgende opdracht uit om jest te installeren.

npm installeren grap

In de pakket.json bestand, configureer jest. Vervang uw bestaande "scripts" -blok door het volgende:

"scripts": {
"testen": "jest --runInBand --detectOpenHandles"
},
"grap": {
"test omgeving": "knooppunt"
},

Maak een nieuw bestand met de naam todo.model.test.js en importeer de mangoestbibliotheek, het todo-model en de functies conenctDB(), dropDB() en dropCollections():

const mangoest = vereisen("mangoest");
const { connectDB, dropDB, dropCollections } = vereisen("./setupdb");
const Todo = vereisen("./todo.model");

U moet de functie connectDB() uitvoeren voordat alle tests worden uitgevoerd. Met Jest kun je de methode beforeAll() gebruiken.

U moet ook opruimfuncties uitvoeren. Voer na elke test de functie dropCollections() en de functie dropDB() uit na alle tests. U hoeft dit niet handmatig te doen en kunt de methoden afterEach() en afterAll() van Jest gebruiken.

Voeg de volgende code toe aan het bestand todo.model.test.js om de database in te stellen en op te schonen.

voor alles(asynchrone () => {
wachten connectDB();
});

ten slotte(asynchrone () => {
wachten dropDB();
});

na elke(asynchrone () => {
wachten dropCollections();
});

U bent nu klaar om de tests te maken.

De eerste test zal controleren of het todo-item met succes in de database is ingevoegd. Het zal controleren of het object-ID aanwezig is in de aangemaakte en of de gegevens daarin overeenkomen met degene die u naar de database hebt verzonden.

Maak een beschrijvingsblok en voeg de volgende code toe.

beschrijven("Todo-model", () => {
het("zou een todo-item succesvol moeten maken", asynchroon () => {
laten geldigTodo = {
item: "De afwas doen",
voltooid: vals,
};
const nieuweTodo = wachten Todo (geldigeTodo);
wachten nieuweTodo.save();
verwachten(nieuwTodo._ID kaart).worden gedefinieerd();
verwachten(nieuwTodo.item).zijn(validTodo.item);
verwachten(nieuwTodo.voltooid).zijn(validTodo.voltooid);
});
});

Deze creëert een nieuw document in de database met de gegevens in de validTodo-variabele. Het geretourneerde object wordt vervolgens gevalideerd tegen de verwachte waarden. Om deze test te laten slagen, moet de geretourneerde waarde een object-ID hebben. Ook moeten de waarden in het item en de ingevulde velden overeenkomen met die in het validTodo-object.

Naast het testen van de normale use case, moet je ook een falende use case testen. Van de tests die we hebben gepland, moet je het mangoestmodel testen met een todo-object, met een ontbrekend verplicht veld en een met een onjuist type.

Voeg als volgt een tweede test toe aan hetzelfde beschrijfblok:

 het("zou moeten mislukken voor todo-item zonder verplichte velden", asynchroon () => {
laten ongeldigTodo = {
item: "De afwas doen",
};
proberen {
const nieuweTodo = nieuwe Todo (ongeldigeTodo);
wachten nieuweTodo.save();
} vangst (fout) {
verwachten(fout).toBeInstanceOf(mangoest.Fout.Validatiefout);
verwachten(fout.fouten.voltooid).worden gedefinieerd();
}
});

Het Todo mangoest-model verwacht zowel het item als de ingevulde velden. Het zou een foutmelding moeten geven als je een taak probeert op te slaan zonder een van deze velden. Deze test gebruikt het try...catch-blok om de gegenereerde fout op te vangen. De test verwacht dat de fouten een validatiefout van een mangoest zijn en voortkomen uit het ontbrekende ingevulde veld.

Om te testen of het model een fout genereert als u waarden van het verkeerde type gebruikt, voegt u de volgende code toe aan het beschrijvende blok.

 het("zou moeten mislukken voor todo-item met velden van het verkeerde type", asynchroon () => {
laten ongeldigTodo = {
item: "De afwas doen",
voltooid: "niet waar"
};
proberen {
const nieuweTodo = nieuwe Todo (ongeldigeTodo);
wachten nieuweTodo.save();
} vangst (fout) {
verwachten(fout).toBeInstanceOf(mangoest.Fout.Validatiefout);
verwachten(fout.fouten.voltooid).worden gedefinieerd();
}
});

Merk op dat de waarde van het ingevulde veld een string is in plaats van een boolean. De test verwacht dat er een validatiefout wordt gegenereerd, omdat het model een booleaanse waarde verwacht.

MongoMemoryServer en Jest vormen een geweldig team

Het mongo-memory-server npm-pakket biedt een eenvoudige oplossing voor het testen van Mongoose-modellen. U kunt dummy-gegevens in het geheugen opslaan zonder de database van uw toepassing aan te raken.

U kunt MongoMemoryServer met Jest gebruiken om tests voor Mongoose-modellen te schrijven. Merk op dat het niet alle mogelijke tests dekt die u voor uw modellen kunt schrijven. Die tests zijn afhankelijk van uw schema.