Jestem w trakcie nauki Node.js i bawiłem się Expressem . Bardzo podoba mi się framework; jednak mam problem ze zrozumieniem, jak napisać test jednostkowy / integracyjny dla trasy.
Możliwość jednostkowego testowania prostych modułów jest łatwa i robiłem to z Mocha ; Jednak moje testy jednostkowe z Express kończą się niepowodzeniem, ponieważ obiekt odpowiedzi, który przekazuję, nie zachowuje wartości.
Trasa-funkcja w trakcie testowania (route / index.js):
exports.index = function(req, res){
res.render('index', { title: 'Express' })
};
Moduł testów jednostkowych:
var should = require("should")
, routes = require("../routes");
var request = {};
var response = {
viewName: ""
, data : {}
, render: function(view, viewData) {
viewName = view;
data = viewData;
}
};
describe("Routing", function(){
describe("Default Route", function(){
it("should provide the a title and the index view name", function(){
routes.index(request, response);
response.viewName.should.equal("index");
});
});
});
Po uruchomieniu to kończy się niepowodzeniem z komunikatem „Błąd: wykryto globalne wycieki: nazwa_widoku, dane”.
Gdzie popełniam błąd, aby to zadziałało?
Czy istnieje lepszy sposób na testowanie jednostkowe kodu na tym poziomie?
Aktualizacja 1. Poprawiony fragment kodu, ponieważ początkowo zapomniałem „it ()”.
Jak inni zalecali w komentarzach, wygląda na to, że kanonicznym sposobem testowania kontrolerów Express jest supertest .
Przykładowy test może wyglądać następująco:
Upside: możesz przetestować cały swój stack za jednym razem.
Wada: czuje się i działa trochę jak testowanie integracyjne.
źródło
integration
i być może ścieżki testowe należy pozostawić testom integracyjnym. Mam na myśli to, że funkcjonalność tras dopasowujących się do ich zdefiniowanych wywołań zwrotnych jest prawdopodobnie już przetestowana przez express.js; jakakolwiek wewnętrzna logika uzyskiwania końcowego wyniku trasy, powinna być w idealnym przypadku modularyzowana poza nią, a te moduły powinny być testowane jednostkowo. Ich interakcję, czyli trasę, należy przetestować pod kątem integracji. Zgodziłbyś się?Doszedłem do wniosku, że jedynym sposobem naprawdę testowania jednostkowego aplikacji ekspresowych jest zachowanie dużej separacji między programami obsługi żądań a podstawową logiką.
W związku z tym logika aplikacji powinna znajdować się w oddzielnych modułach, które można
require
przetestować d i jednostkowo, i mieć minimalną zależność od klas Express Request i Response jako takich.Następnie w programach obsługi żądań należy wywołać odpowiednie metody podstawowych klas logiki.
Podam przykład, gdy zakończę restrukturyzację mojej obecnej aplikacji!
Chyba coś takiego ? (Zapraszam do rozwidlenia istoty lub komentarza, wciąż to badam).
Edytować
Oto mały przykład, inline. Zobacz sedno, aby uzyskać bardziej szczegółowy przykład.
źródło
Najłatwiejszym sposobem przetestowania HTTP za pomocą express jest kradzież pomocnika http TJ-a
Ja osobiście używać swojego pomocnika
Jeśli chcesz dokładnie przetestować obiekt tras, przekaż poprawne makiety
źródło
jeśli testy jednostkowe z express 4, zwróć uwagę na ten przykład od gjohnson :
źródło
Też się nad tym zastanawiałem, ale specjalnie dla testów jednostkowych, a nie testów integracyjnych. To jest to, co teraz robię
Gdzie routerObj jest po prostu
{router: expressRouter, path: '/api'}
. Następnie ładuję podroutery za pomocą,var loginRouterInfo = require('./login')(express.Router({mergeParams: true}));
a aplikacja ekspresowa wywołuje funkcję init, przyjmując jako parametr router ekspresowy. Następnie initRouter wywołujerouter.use(loginRouterInfo.path, loginRouterInfo.router);
zamontowanie routera podrzędnego.Podrouter można przetestować za pomocą:
źródło
Aby uzyskać testowanie jednostkowe zamiast testowania integracji, wyśmiałem obiekt odpowiedzi modułu obsługi żądań.
Następnie, aby przeprowadzić testy integracji, możesz mockować swój endpointHandler i wywołać punkt końcowy za pomocą supertestu .
źródło
W moim przypadku jedyne, co chciałem sprawdzić, to czy został wezwany właściwy handler. Chciałem użyć supertestu, aby zmniejszyć prostotę wysyłania żądań do oprogramowania pośredniczącego routingu. Używam Typescript a i jest to rozwiązanie, które zadziałało
Trasy
Testy
Miałem pewne problemy, aby kpina zadziałała. ale użycie jest.doMock i kolejność, którą widzisz w przykładzie, sprawia, że działa.
źródło