Testowanie modeli Mongoose może być wyzwaniem, ponieważ musisz pisać testy, które nie kolidują z rzeczywistą bazą danych. Pakiet serwera pamięci MongoDB oferuje proste rozwiązanie. Umożliwia przechowywanie danych testowych w pamięci aplikacji.
W tym samouczku utworzysz prosty model Mongoose i napiszesz testy przy użyciu Jest i serwera pamięci MongoDB.
Co to jest serwer pamięci MongoDB?
Ostatnią rzeczą, jakiej chcesz, jest zapisywanie fałszywych danych w prawdziwej bazie danych, co może się zdarzyć, jeśli połączysz się z nią podczas testowania. Zamiast tego możesz zdecydować się na użycie oddzielnej lokalnej instancji MongoDB do przechowywania danych. Chociaż to działa, jest to niewykonalne, jeśli twoje testy są uruchamiane w chmurze. Co więcej, łączenie i odpytywanie prawdziwej bazy danych podczas każdego testu może być kosztowne.
Serwer pamięci MongoDB, jednak rozkręca prawdziwy serwer MongoDB i umożliwia przechowywanie danych testowych w pamięci. To sprawia, że jest to szybsze niż korzystanie z lokalnej bazy danych MongoDB, ponieważ dane nie są zapisywane na dysku fizycznym.
Tworzenie modelu mangusty
Modele Mongoose zapewniają interfejs do łączenia się z bazą danych MongoDB. Aby je utworzyć, musisz je skompilować ze schematu Mongoose, który definiuje twój model danych MongoDB. Ten samouczek użyje schematu dla dokumentu do zrobienia. Będzie zawierał tytuł i wypełnione pola.
Uruchom następujące polecenie w terminalu, aby utworzyć nowy folder i przejść do niego.
mkdir test-modelu-mangusty
płyta CD test-model-mangusty
Zainicjuj npm za pomocą następującego polecenia:
npm początek -y
The -y flaga nakazuje npm wygenerowanie pliku package.json z wartościami domyślnymi.
Wykonaj to polecenie, aby zainstalować mangusta pakiet:
npm zainstalować mangusta
Utwórz nowy plik o nazwie todo.model.js i zdefiniuj schemat zadań:
stały mangusta = wymagać("mangusta")
stały { Schemat } = mangusta
stały TodoSchema = Nowy Schemat({
przedmiot: {
rodzaj: Strunowy,
wymagany: PRAWDA
},
ukończony: {
rodzaj: Boole'a,
wymagany: PRAWDA
}
})
Na końcu tego pliku utwórz i wyeksportuj model rzeczy do zrobienia:
moduł.eksport = mongoose.model("Todo", TodoSchema)
Planowanie testów
Pisząc testy, chcesz wcześniej zaplanować, co będziesz testować. Gwarantuje to, że testujesz całą funkcjonalność swojego modelu.
Z utworzonego przez nas modelu Mongoose zadanie powinno zawierać element typu String oraz wypełnione pole typu Boolean. Oba te pola są wymagane. Oznacza to, że nasz test powinien przynajmniej zapewniać:
- Poprawne pozycje zostały pomyślnie zapisane w bazie danych.
- Przedmioty bez wymaganych pól nie są zapisywane.
- Elementy z polami nieprawidłowego typu nie są zapisywane.
Napiszemy te testy w jednym bloku testowym, ponieważ są one powiązane. W Jest definiujesz ten blok testowy za pomocą opisać funkcjonować. Na przykład:
opisać('Test modelu Todo', () => {
// Twoje testy idą tutaj
}
Konfigurowanie bazy danych
Aby skonfigurować serwer pamięci MongoDB, utworzysz nową instancję serwera pamięci Mongo i połączysz się z Mongoose. Stworzysz również funkcje, które będą odpowiedzialne za zrzucanie wszystkich kolekcji w bazie danych i odłączanie się od instancji serwera pamięci Mongo.
Uruchom następujące polecenie, aby zainstalować serwer pamięci mongodb.
npm zainstalować mongodb-pamięć-serwer
Utwórz nowy plik o nazwie setuptestdb.js i importuj mongoose i mongodb-memory-server.
stały mangusta = wymagać("mangusta");
stały { MongoMemoryServer } = wymagać(„serwer pamięci mongodb”);
Następnie utwórz funkcję connectDB(). Ta funkcja tworzy nową instancję serwera pamięci Mongo i łączy się z Mongoose. Uruchomisz go przed wszystkimi testami, aby połączyć się z testową bazą danych.
wynajmować mongo = zero;
stały poł.DB = asynchroniczny () => {
mongo = czekać na MongoMemoryServer.create();
stały uri = mongo.getUri();
czekać na mangusta.connect (uri, {
użyj NewUrlParser: PRAWDA,
użyj ujednoliconej topologii: PRAWDA,
});
};
Utwórz funkcję dropDB(), dodając następujący kod. Ta funkcja usuwa bazę danych, zamyka połączenie Mongoose i zatrzymuje instancję serwera pamięci Mongo. Ta funkcja zostanie uruchomiona po zakończeniu wszystkich testów.
stały dropDB = asynchroniczny () => {
jeśli (mongo) {
czekać namangusta.połączenie.dropBazadanych();
czekać namangusta.połączenie.blisko();
czekać na mongo.stop();
}
};
Ostatnia funkcja, którą utworzysz, nazywa się dropCollections(). Porzuca wszystkie stworzone kolekcje Mongoose. Uruchomisz go po każdym teście.
stały dropCollections = asynchroniczny () => {
jeśli (mongo) {
stały kolekcje = czekać na połączenie.db.collections();
dla (wynajmować kolekcja z kolekcje) {
czekać na kolekcja.usuń();
}
}
};
Na koniec wyeksportuj funkcje conenctDB(), dropDB() i dropCollections().
moduł.eksport = { connectDB, dropDB, dropCollections}
Pisanie testów
Jak wspomniano, do pisania testów użyjesz Jest. Uruchom następujące polecenie, aby zainstalować jest.
npm zainstalować żart
w pakiet.json plik, konfiguruj jest. Zastąp istniejący blok „skrypty” następującym:
"skrypty": {
"test": "jest --runInBand --detectOpenHandles"
},
"żart": {
"Środowisko testowe": "węzeł"
},
Utwórz nowy plik o nazwie todo.model.test.js i zaimportuj bibliotekę mangoose, model todo oraz funkcje conenctDB(), dropDB() i dropCollections():
stały mangusta = wymagać("mangusta");
stały { connectDB, dropDB, dropCollections } = wymagać("./setupdb");
stały Do zrobienia = wymagać("./todo.model");
Musisz uruchomić funkcję connectDB() przed uruchomieniem wszystkich testów. Dzięki Jest możesz użyć metody beforeAll().
Musisz także uruchomić funkcje czyszczenia. Po każdym teście uruchom funkcję dropCollections() i dropDB() po wszystkich testach. Nie musisz tego robić ręcznie i możesz użyć metod afterEach() i afterAll() z Jest.
Dodaj następujący kod do pliku todo.model.test.js, aby skonfigurować i wyczyścić bazę danych.
przed wszystkim(asynchroniczny () => {
czekać na connectDB();
});w końcu(asynchroniczny () => {
czekać na dropDB();
});
po każdym(asynchroniczny () => {
czekać na dropCollections();
});
Jesteś teraz gotowy do tworzenia testów.
Pierwszy test sprawdzi, czy pozycja do zrobienia została pomyślnie wstawiona do bazy danych. Sprawdza, czy identyfikator obiektu jest obecny w utworzonym do i czy dane w nim są zgodne z tymi, które wysłałeś do bazy danych.
Utwórz blok opisu i dodaj następujący kod.
opisać("Model rzeczy do zrobienia", () => {
to("powinien pomyślnie utworzyć element do zrobienia", asynchroniczny () => {
wynajmować ważneTodo = {
przedmiot: "Zmyj naczynia",
zakończony: fałszywy,
};
stały noweTodo = czekać na Todo (ważneTodo);
czekać na noweTodo.zapisz();
oczekiwać(nowośćTodo._ID).zostać określone();
oczekiwać(nowośćTodo.przedmiot).być(validTodo.przedmiot);
oczekiwać(nowośćTodo.zakończony).być(validTodo.zakończony);
});
});
Ten tworzy nowy dokument w bazie danych zawierające dane w zmiennej validTodo. Zwrócony obiekt jest następnie sprawdzany pod kątem oczekiwanych wartości. Aby ten test zakończył się pomyślnie, zwracana wartość powinna mieć identyfikator obiektu. Ponadto wartości w elemencie i wypełnionych polach powinny odpowiadać wartościom w obiekcie validTodo.
Oprócz testowania normalnego przypadku użycia, musisz również przetestować przypadek, w którym wystąpił błąd. Z testów, które zaplanowaliśmy, musisz przetestować model mangusty z obiektem do zrobienia, z brakującym polem wymaganym i jednym z niepoprawnym typem.
Dodaj drugi test do tego samego bloku opisu w następujący sposób:
to("powinien się nie powieść dla pozycji do zrobienia bez wymaganych pól", asynchroniczny () => {
wynajmować nieprawidłowe zadanie = {
przedmiot: "Zmyj naczynia",
};
próbować {
stały noweTodo = Nowy Todo (nieprawidłoweTodo);
czekać na noweTodo.zapisz();
} złapać (błąd) {
oczekiwać(błąd).toBeInstanceOf(mangusta.Błąd.Błąd walidacji);
oczekiwać(błąd.błędy.zakończony).zostać określone();
}
});
Model mangusty Todo oczekuje zarówno pozycji, jak i wypełnionych pól. Powinien pojawić się błąd, jeśli spróbujesz zapisać zadanie bez jednego z tych pól. Ten test używa bloku try…catch do wychwycenia zgłoszonego błędu. Test oczekuje, że błędy będą błędem walidacji mangusty i wynikają z brakującego wypełnionego pola.
Aby sprawdzić, czy model zgłasza błąd, jeśli używasz wartości niewłaściwego typu, dodaj następujący kod do bloku opisu.
to("powinien zakończyć się niepowodzeniem dla pozycji do zrobienia z polami niewłaściwego typu", asynchroniczny () => {
wynajmować nieprawidłowe zadanie = {
przedmiot: "Zmyj naczynia",
zakończony: "Fałszywy"
};
próbować {
stały noweTodo = Nowy Todo (nieprawidłoweTodo);
czekać na noweTodo.zapisz();
} złapać (błąd) {
oczekiwać(błąd).toBeInstanceOf(mangusta.Błąd.Błąd walidacji);
oczekiwać(błąd.błędy.zakończony).zostać określone();
}
});
Zauważ, że wartość wypełnionego pola jest ciągiem znaków, a nie wartością logiczną. Test oczekuje, że zostanie zgłoszony błąd walidacji, ponieważ model oczekuje wartości logicznej.
MongoMemoryServer i Jest tworzą świetny zespół
Pakiet mongo-memory-server npm zapewnia łatwe rozwiązanie do testowania modeli Mongoose. Możesz przechowywać fikcyjne dane w pamięci bez dotykania bazy danych aplikacji.
MongoMemoryServer z Jest można używać do pisania testów dla modeli Mongoose. Zauważ, że nie obejmuje wszystkich możliwych testów, które możesz napisać dla swoich modeli. Te testy będą zależeć od twojego schematu.