Тестването, въпреки че може да отнеме много време, е важна стъпка в цикъла на разработка на всяко приложение. Той гарантира, че хващате бъгове и проблеми на ранен етап, преди да изпратите кода до производство.
Можете да използвате Jest, за да тествате Express Rest API. След като създадете прост CRUD API, открийте как да пишете тестове за всяка крайна точка.
Какво е Jest?
Има много библиотеки за тестване на JavaScript, от които можете да избирате, но шега е най-лесно да започнете. Това е библиотека за тестване, разработена от Facebook, използвана най-вече за тестване на React проекти. Можете обаче да го използвате и за тестване на Node и други базирани на JavaScript проекти. Той е разработен върху Jasmine, друг инструмент за тестване, и идва в комплект със собствена библиотека за твърдения.
Въпреки че няма да имате нужда от библиотека с твърдения, за да пишете тестове в Jest, ще трябва да използвате инструмент, за да правите HTTP заявки. Тази статия използва SuperTest.
Какво е SuperTest?
СуперТест
е библиотека за тестване на възли за HTTP повиквания. Той разширява библиотеката за тестване на суперагенти и ви позволява да правите заявки като GET, POST, PUT и DELETE.SuperTest предоставя обект на заявка, който можете да използвате, за да правите HTTP заявки.
конст заявка = изискват("супертест")
заявка("https://icanhazdadjoke.com")
.get('/slack')
.край(функция(грешка, рез) {
ако (грешка) хвърлям греша;
конзола.дневник(рез.тяло.прикачени файлове);
});
Тук подавате основния URL адрес на API към обекта на заявката и след това свързвате HTTP метода с останалата част от URL адреса. The край() методът извиква API сървъра и функцията за обратно извикване обработва неговия отговор.
След като получите отговор от API, можете да използвате Jest, за да го потвърдите.
Създайте Express API
За да тествате вашите собствени крайни точки на API, трябва да създадете REST API първи. API, който ще създадете, е доста прост. Той вмъква, извлича, актуализира и изтрива елементи от масив.
Започнете със създаване на нова директория, наречена node-jest, и инициализиране на npm.
mkdir възел-jest
npm init -y
След това създайте нов файл, наречен index.js и създайте Express сървър.
конст експрес = изискват("експресен")
конст приложение = експрес()
app.listen (3000, () => console.log("Слушане на порт 3000"))
Тествайте крайната точка GET /todos
Първата крайна точка, която ще създадете, е крайната точка GET /todos. Връща всички елементи в масива. В index.js добавете следното.
конст todos = [
];
// Вземете всички задачи
app.get("/todos", (req, res) => {
връщанерез.състояние(200).json({
данни: todos,
грешка: нула,
});
});
Обърнете внимание, че отговорът има код на състоянието 200 и JSON обект, съдържащ елемента със задачи в масив, наречен данни, и съобщение за грешка. Това е, което ще тествате с помощта на Jest.
Сега инсталирайте Jest и SuperTest:
npm Инсталирай майтап супертест
След това добавете тестов скрипт package.json както следва:
{
"скриптове": {
"тест": "шега"
}
}
Преди да започнете да пишете свои собствени тестове, трябва да разберете как да пишете основен тест в Jest.
Помислете за следната функция:
функциясума(а, б) {
връщане a + b;
}
модул.износ = сума;
В тестовия файл трябва да:
- Импортирайте функцията.
- Опишете какво трябва да направи тестът.
- Извикайте функцията.
- Утвърдете очаквания отговор с действителния отговор от функцията.
конст {сума} = изискват("./сума")
описвам("Сума от два елемента", async() => {
тест("Трябва да върне 4", () => {
очаквам(сума(2,2)).да бъде(4)
})
})
The описвам ключовата дума указва групата тестове и тест декларацията уточнява конкретния тест. Ако стойността, върната от функцията, съвпада с предадената стойност да бъде, тестът преминава.
Когато тествате крайни точки на API, вие няма да извиквате функция, а изпращате заявка с помощта на SuperTest или друга HTTP клиентска библиотека.
Връщайки се към крайната точка GET, създайте нов файл, наречен api.test.js. Това е мястото, където ще напишете всички тестове за крайни точки. Наименуване на тестовия файл с a .тест infix гарантира, че Jest го разпознава като тестов файл.
В api.test.js импортирайте supertest и задайте основния URL така:
конст заявка = изискват("супертест")
конст baseURL = "http://localhost: 3000"
След това създайте първия тест в блока за описание:
описвам("GET /todos", () => {
конст newTodo = {
документ за самоличност: крипто.randomUUID(),
вещ: "Пия вода",
завършен: невярно,
}
преди всички(асинхронен () => {
// настройка на задачата
изчакайте заявка (baseURL).post("/todo").изпрати (нова задача);
})
след всичко(асинхронен () => {
изчакайте заявка (базов URL).delete(`/задача/${newTodo.id}`)
})
то("трябва да върне 200", асинхронен () => {
конст отговор = изчакайте заявка (базов URL).get("/todos");
очаквам(отговор.statusCode).да бъде(200);
очаквам(отговор.тяло.грешка).да бъде(нула);
});
то("трябва да върне todos", асинхронен () => {
конст отговор = изчакайте заявка (базов URL).get("/todos");
очаквам (response.body.data.length >= 1).да бъде(вярно);
});
});
Преди да стартирате тестовете, ще трябва да дефинирате функции за настройка и разглобяване. Тези функции ще попълнят масива със задачи с елемент преди теста и ще изтрият фиктивните данни след всеки тест.
Кодът, който се изпълнява преди всички тестове, е във функцията beforeAll(). Кодът, който се изпълнява след всички тестове, е във функцията afterAll().
В този пример вие просто натискате крайните точки POST и DELETE за всяка. В реално приложение вероятно бихте се свързали с фиктивна база данни, съдържаща тестовите данни.
В този тест първо направихте заявка до крайната точка GET /todos и сравнихте изпратения отговор с очакваните резултати. Този набор от тестове ще премине, ако отговорът има HTTP код на състоянието от 200, данните не са празни и съобщението за грешка е нула.
Тествайте крайната точка POST /todo
В index.js създайте крайната точка POST /todo:
app.post("/todo", (req, res) => {
опитвам {
конст { id, item, completed } = req.body;
конст newTodo = {
документ за самоличност,
вещ,
завършен,
};
todos.натискане(newTodo);
връщанерез.състояние(201).json({
данни: todos,
грешка: нула,
});
} улов (грешка) {
връщанерез.състояние(500).json({
данни: нула,
грешка: грешка,
});
}
});
В този тест ще трябва да изпратите подробностите за Todo в тялото на заявката, като използвате метода send().
заявка (baseURL).post("/todo").изпрати (нова задача)
Заявката POST /todo трябва да върне код на състоянието 201 и масива todos с новия елемент, добавен в края. Ето как може да изглежда тестът:
описвам("POST /todo", () => {
конст newTodo = {
// да направя
}
след всичко(асинхронен () => {
изчакайте заявка (базов URL).delete(`/задача/${newTodo.id}`)
})
то("трябва да добави елемент към масива todos", асинхронен () => {
конст отговор = изчакайте заявка (baseURL).post("/todo").send(newTodo);
конст lastItem = response.body.data[response.body.data.length-1]
очаквам(отговор.statusCode).да бъде(201);
очаквам(последен елемент.вещ).да бъде(newTodo["вещ"]);
очаквам(последен елемент.завършен).да бъде(newTodo["завършен"]);
});
});
Тук предавате данните за задачи на метода send() като аргумент. Отговорът трябва да има код на състоянието 201 и също така да съдържа всички елементи със задачи в обект с данни. За да проверите дали todo действително е създадено, проверете дали последният запис в върнатите todos съвпада с този, който сте изпратили в заявката.
Крайната точка PUT /todos/:id трябва да върне актуализирания елемент:
app.put("/todos/:id", (req, res) => {
опитвам {
конст id = req.params.id
конст todo = todos.find((todo) => todo.id == id);
if(!todo) {
хвърлямновГрешка(„Задачата не е намерена“)
}
todo.completed = req.body.completed;
връщанерез.състояние(201).json({
данни: задачи,
грешка: нула,
});
} улов (грешка) {
връщанерез.състояние(500).json({
данни: нула,
грешка: грешка,
});
}
});
Тествайте отговора, както следва:
описвам("Актуализирайте една задача", () => {
конст newTodo = {
// да направя
}
преди всички(асинхронен () => {
изчакайте заявка (baseURL).post("/todo").изпрати (нова задача);
})
след всичко(асинхронен () => {
изчакайте заявка (базов URL).delete(`/задача/${newTodo.id}`)
})
то("трябва да актуализира елемента, ако съществува", асинхронен () => {
конст отговор = изчакайте заявка (базов URL).put(`/todos/${newTodo.id}`).изпрати({
завършен: вярно,
});
очаквам(отговор.statusCode).да бъде(201);
очаквам(отговор.тяло.данни.завършен).да бъде(вярно);
});
});
Завършената стойност в тялото на отговора трябва да е истина. Не забравяйте да включите идентификатора на елемента, който искате да актуализирате, в URL адреса.
Тествайте крайната точка DELETE /todos/:id
В index.js създайте крайната точка DELETE. Трябва да върне данните за задачи без изтрития елемент.
app.delete("/todos/:id", (req, res) => {
опитвам {
конст id = req.params.id
конст todo = todos[0]
if (todo) {
todos.снаждане(документ за самоличност, 1)
}
връщанерез.състояние(200).json({
данни: todos,
грешка: нула,
});
} улов (грешка) {
връщанерез.състояние(500).json({
данни: нула,
грешка: грешка,
});
}
});
За да тествате крайната точка, можете да проверите дали изтритият елемент все още съществува в върнатите данни:
описвам("Изтриване на една задача", () => {
конст newTodo = {
// да направя
}
преди всички(асинхронен () => {
изчакайте заявка (baseURL).post("/todo").изпрати (нова задача);
})
то("трябва да изтрие един елемент", асинхронен () => {
конст отговор = изчакайте заявка (базов URL).delete(`/todos/${newTodo.id}`);
конст todos = response.body.data
конст съществува = todos.find (todo => {
newTodo.id == todoId
})
очаквам (съществува).toBe(недефиниран)
});
});
Данните, върнати от крайната точка DELETE, не трябва да съдържат изтрития елемент. Тъй като върнатите елементи са в масив, можете да използвате Array[id], за да проверите дали API е изтрил правилно елемента. Резултатът трябва да е фалшив.
Създаване на REST API
В тази статия научихте как да тествате Express Rest API с помощта на Jest API. Написахте тестове за HTTP заявките GET, PUT, POST и DELETE и видяхте как да изпратите данни до крайната точка в URL адреса и заявката. Трябва да можете да приложите тези знания, когато тествате своя собствен Rest API.