Testování, i když může být časově náročné, je důležitým krokem ve vývojovém cyklu jakékoli aplikace. Zajišťuje, že včas zachytíte chyby a problémy, než odešlete kód do produkce.

Jest můžete použít k testování Express Rest API. Po vytvoření jednoduchého rozhraní CRUD API zjistěte, jak psát testy pro každý koncový bod.

Co je Jest?

Existuje mnoho testovacích knihoven JavaScriptu, ze kterých si můžete vybrat, ale Žert je nejjednodušší začít. Je to testovací knihovna vyvinutá Facebookem, většinou se používá k testování projektů React. Můžete jej však také použít k testování Node a dalších projektů založených na JavaScriptu. Byl vyvinut nad dalším testovacím nástrojem Jasmine a je dodáván s vlastní knihovnou tvrzení.

I když k psaní testů v Jestu nebudete potřebovat knihovnu asercí, budete muset použít nástroj pro vytváření požadavků HTTP. Tento článek používá SuperTest.

Co je to SuperTest?

SuperTest je knihovna pro testování uzlů pro volání HTTP. Rozšiřuje knihovnu testování superagentů a umožňuje vám zadávat požadavky jako GET, POST, PUT a DELETE.

SuperTest poskytuje objekt požadavku, který můžete použít k vytváření požadavků HTTP.

konst žádost = vyžadovat("supertest")
žádost("https://icanhazdadjoke.com")
.dostat('/slack')
.konec(funkce(chyba, res) {
-li (chybovat) házet chybovat;
řídicí panel.log(res.tělo.přílohy);
});

Zde předáte základní adresu URL rozhraní API objektu požadavku a poté zřetězíte metodu HTTP se zbytkem adresy URL. The konec() metoda volá server API a funkce zpětného volání zpracovává jeho odpověď.

Jakmile získáte odpověď z API, můžete ji pomocí Jest ověřit.

Vytvořte expresní API

Chcete-li otestovat své vlastní koncové body API, musíte je vytvořit rozhraní REST API První. API, které vytvoříte, je poměrně jednoduché. Vkládá, načítá, aktualizuje a odstraňuje položky z pole.

Začněte vytvořením nového adresáře s názvem node-jest a inicializací npm.

mkdir node-jest
npm init -y

Dále vytvořte nový soubor s názvem index.js a vytvořit expresní server.

konst vyjádřit = vyžadovat("vyjádřit")
konst app = express()
app.listen (3000, () => console.log("Poslech na portu 3000"))

Otestujte koncový bod GET /todos

První koncový bod, který vytvoříte, je koncový bod GET /todos. Vrátí všechny položky v poli. V index.js přidejte následující.

konst todos = [
];
// Získejte všechny úkoly
app.get("/todos", (req, res) => {
vrátit seres.postavení(200).json({
údaje: todos,
chyba: nula,
});
});

Všimněte si, že odpověď má stavový kód 200 a objekt JSON obsahující položku úkolu v poli s názvem data a chybovou zprávu. To je to, co budete testovat pomocí Jestu.

Nyní nainstalujte Jest a SuperTest:

npm Nainstalujte vtip supertest

Poté přidejte testovací skript package.json jak následuje:

{
"skripty": {
"test": "žert"
}
}

Než začnete psát své vlastní testy, měli byste pochopit, jak napsat základní test v Jestu.

Zvažte následující funkci:

funkcesoučet(a, b) {
vrátit se a + b;
}
modul.exportů = součet;

V testovacím souboru musíte:

  • Importujte funkci.
  • Popište, co by měl test dělat.
  • Zavolejte funkci.
  • Uveďte očekávanou odezvu se skutečnou odezvou funkce.
konst { součet } = vyžadovat("./součet")
popsat("Součet dvou položek", async() => {
test("Mělo by se vrátit 4", () => {
očekávat(součet(2,2)).být(4)
})
})

The popsat klíčové slovo určuje skupinu testů a test příkaz specifikuje konkrétní test. Pokud se hodnota vrácená funkcí shoduje s hodnotou předanou být, test projde.

Při testování koncových bodů API nebudete volat funkci, ale posílat požadavek pomocí SuperTest nebo jiné klientské knihovny HTTP.

Vraťte se ke koncovému bodu GET a vytvořte nový soubor s názvem api.test.js. Zde budete psát všechny testy koncových bodů. Pojmenování testovacího souboru pomocí a .test infix zajišťuje, že jej Jest rozpozná jako testovací soubor.

V api.test.js importujte supertest a nastavte základní URL takto:

konst žádost = vyžadovat("supertest")
konst baseURL = "http://localhost: 3000"

Dále vytvořte první test v bloku description:

popsat("GET /todos", () => {
konst newTodo = {
id: krypto.randomUUID(),
položka: "Pít vodu",
dokončeno: Nepravdivé,
}
předtímVše(asynchronní () => {
// nastavení úkolu
čekat na žádost (baseURL).post("/todo").odeslat (newTodo);
})
po všem(asynchronní () => {
čekat požadavek (baseURL).delete(`/todo/${newTodo.id}`)
})
to("měl vrátit 200", async () => {
konst odpověď = čekat request (baseURL).get("/todos");
očekávat(Odezva.statusCode).být(200);
očekávat(Odezva.tělo.chyba).být(nula);
});
to("by se měl vrátit k úkolům", async () => {
konst odpověď = čekat request (baseURL).get("/todos");
očekávat (response.body.data.length >= 1).být(skutečný);
});
});

Před spuštěním testů budete muset definovat funkce nastavení a odstranění. Tyto funkce naplní pole úkolů položkou před testem a po každém testu vymažou fiktivní data.

Kód, který se spustí před všemi testy, je ve funkci beforeAll(). Kód, který se spustí po všech testech, je ve funkci afterAll().

V tomto příkladu jednoduše stisknete koncové body POST a DELETE pro každý z nich. Ve skutečné aplikaci byste se pravděpodobně připojili k simulované databázi obsahující testovací data.

V tomto testu jste nejprve zadali požadavek na koncový bod GET /todos a porovnali odeslanou odpověď s očekávanými výsledky. Tato testovací sada projde, pokud má odpověď příponu Stavový kód HTTP 200, data nejsou prázdná a chybová zpráva je null.

Otestujte koncový bod POST /todo

V index.js vytvořte koncový bod POST /todo:

app.post("/todo", (req, res) => {
Snaž se {
konst { id, položka, dokončeno } = req.body;
konst newTodo = {
id,
položka,
dokončeno,
};
todos.TLAČIT(newTodo);
vrátit seres.postavení(201).json({
údaje: todos,
chyba: nula,
});
} úlovek (chyba) {
vrátit seres.postavení(500).json({
data: nula,
chyba: chyba,
});
}
});

V tomto testu budete muset odeslat podrobnosti o úkolu v těle požadavku pomocí metody send().

požadavek (baseURL).post("/todo").odeslat (newTodo)

Požadavek POST /todo by měl vrátit stavový kód 201 a pole úkolů s novou položkou přidanou na konci. Takto může test vypadat:

popsat("POST /todo", () => {
konst newTodo = {
// dělat
}
po všem(asynchronní () => {
čekat požadavek (baseURL).delete(`/todo/${newTodo.id}`)
})
to("by měl přidat položku do pole todos", async () => {
konst odpověď = čekat požadavek (baseURL).post("/todo").send(newTodo);
konst lastItem = response.body.data[response.body.data.length-1]
očekávat(Odezva.statusCode).být(201);
očekávat(poslední položka.položka).být(newTodo["položka"]);
očekávat(poslední položka.dokončeno).být(newTodo["dokončeno"]);
});
});

Zde předáváte data úkolu metodě send() jako argument. Odpověď by měla mít stavový kód 201 a také obsahovat všechny položky úkolů v datovém objektu. Chcete-li otestovat, zda byl úkol skutečně vytvořen, zkontrolujte, zda poslední záznam ve vrácených úkolech odpovídá tomu, který jste odeslali v požadavku.

Koncový bod PUT /todos/:id by měl vrátit aktualizovanou položku:

app.put("/todos/:id", (req, res) => {
Snaž se {
konst id = req.params.id
konst todo = todos.find((todo) => todo.id == id);
if(!todo) {
házetNovýChyba("Todo nenalezeno")
}
todo.completed = req.body.completed;
vrátit seres.postavení(201).json({
údaje: úkol,
chyba: nula,
});
} úlovek (chyba) {
vrátit seres.postavení(500).json({
data: nula,
chyba: chyba,
});
}
});

Otestujte odpověď následovně:

popsat("Aktualizujte jeden úkol", () => {
konst newTodo = {
// dělat
}
předtímVše(asynchronní () => {
čekat na žádost (baseURL).post("/todo").odeslat (newTodo);
})
po všem(asynchronní () => {
čekat požadavek (baseURL).delete(`/todo/${newTodo.id}`)
})
to("měl by aktualizovat položku, pokud existuje", async () => {
konst odpověď = čekat požadavek (baseURL).put(`/todos/${newTodo.id}`).poslat({
dokončeno: skutečný,
});
očekávat(Odezva.statusCode).být(201);
očekávat(Odezva.tělo.data.dokončeno).být(skutečný);
});
});

Dokončená hodnota v těle odpovědi by měla být pravdivá. Nezapomeňte do adresy URL zahrnout ID položky, kterou chcete aktualizovat.

Otestujte koncový bod DELETE /todos/:id

V index.js vytvořte koncový bod DELETE. Měl by vrátit data úkolu bez smazané položky.

app.delete("/todos/:id", (req, res) => {
Snaž se {
konst id = req.params.id
konst todo = todos[0]
if (todo) {
todos.split(id, 1)
}
vrátit seres.postavení(200).json({
údaje: todos,
chyba: nula,
});
} úlovek (chyba) {
vrátit seres.postavení(500).json({
data: nula,
chyba: chyba,
});
}
});

Chcete-li otestovat koncový bod, můžete zkontrolovat, zda odstraněná položka stále existuje ve vrácených datech:

popsat("Smazat jeden úkol", () => {
konst newTodo = {
// dělat
}
předtímVše(asynchronní () => {
čekat na žádost (baseURL).post("/todo").odeslat (newTodo);
})
to("by měl smazat jednu položku", async () => {
konst odpověď = čekat požadavek (baseURL).delete(`/todos/${newTodo.id}`);
konst todos = response.body.data
konst existuje = todos.find (todo => {
newTodo.id == todoId
})
očekávat (existuje).toBe(nedefinováno)
});
});

Data vrácená z koncového bodu DELETE by neměla obsahovat odstraněnou položku. Vzhledem k tomu, že vrácené položky jsou v poli, můžete použít Array[id] ke kontrole, zda API odstranilo položku správně. Výsledek by měl být nepravdivý.

Vytváření REST API

V tomto článku jste se naučili, jak testovat Express Rest API pomocí Jest API. Napsali jste testy pro požadavky GET, PUT, POST a DELETE HTTP a viděli jste, jak odeslat data do koncového bodu v adrese URL a požadavku. Tyto znalosti byste měli být schopni uplatnit při testování vlastního Rest API.