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.

instagram viewer

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.