O teste, embora possa ser demorado, é uma etapa importante no ciclo de desenvolvimento de qualquer aplicativo. Ele garante que você detecte bugs e problemas antes de enviar o código para a produção.
Você pode usar o Jest para testar uma API Express Rest. Depois de criar uma API CRUD simples, descubra como escrever testes para cada endpoint.
O que é Jéstia?
Existem muitas bibliotecas de teste JavaScript que você pode escolher, mas brincadeira é o mais fácil para começar. É uma biblioteca de testes desenvolvida pelo Facebook, usada principalmente para testar projetos React. No entanto, você também pode usá-lo para testar Node e outros projetos baseados em JavaScript. Ele foi desenvolvido em cima do Jasmine, outra ferramenta de teste, e vem com sua própria biblioteca de asserções.
Embora você não precise de uma biblioteca de asserções para escrever testes no Jest, precisará usar uma ferramenta para fazer solicitações HTTP. Este artigo usa SuperTest.
O que é SuperTeste?
SuperTeste é uma biblioteca de teste Node para chamadas HTTP. Ele estende a biblioteca de testes do superagente e permite que você faça solicitações como GET, POST, PUT e DELETE.
O SuperTest fornece um objeto de solicitação que você pode usar para fazer solicitações HTTP.
const pedido = exigir("superteste")
solicitar("https://icanhazdadjoke.com")
.pegue('/slack')
.fim(função(err, res) {
E se (errar) lançar errar;
console.registro(res.corpo.anexos);
});
Aqui, você passa a URL base da API para o objeto de solicitação e, em seguida, encadeia o método HTTP com o restante da URL. o fim() O método chama o servidor de API e a função de retorno de chamada trata sua resposta.
Depois de obter a resposta da API, você pode usar o Jest para validá-la.
Criar uma API Expressa
Para testar seus próprios endpoints de API, você precisa criar uma API REST primeiro. A API que você criará é bem simples. Ele insere, recupera, atualiza e exclui itens de uma matriz.
Comece criando um novo diretório chamado node-jest e inicializando o npm.
mkdir node-jest
npm init -y
Em seguida, crie um novo arquivo chamado index.js e crie o servidor expresso.
const expresso = exigir("expressar")
const aplicativo = expresso()
app.listen (3000, () => console.log("Ouvindo na porta 3000"))
Teste o endpoint GET /todos
O primeiro endpoint que você criará é o endpoint GET /todos. Ele retorna todos os itens do array. Em index.js, adicione o seguinte.
const todos = [
];
// Pega todos
app.get("/todos", (req, res) => {
Retornares.status(200).json({
dados: todos,
erro: nulo,
});
});
Observe que a resposta tem um código de status de 200 e um objeto JSON contendo o item de pendências em uma matriz chamada data e uma mensagem de erro. Isso é o que você testará usando o Jest.
Agora, instale o Jest e o SuperTest:
npm instalar superteste de brincadeira
Em seguida, adicione um script de teste em pacote.json do seguinte modo:
{
"roteiros": {
"teste": "brincadeira"
}
}
Antes de começar a escrever seus próprios testes, você deve entender como escrever um teste básico no Jest.
Considere a seguinte função:
funçãosoma(a, b) {
Retorna a + b;
}
módulo.exportações = soma;
No arquivo de teste, você precisa:
- Importe a função.
- Descreva o que o teste deve fazer.
- Chame a função.
- Afirme a resposta esperada com a resposta real da função.
const { soma } = exigir("./soma")
descrever("Soma de dois itens", assíncrono() => {
teste("Deve retornar 4", () => {
Espero(soma(2,2)).ser(4)
})
})
o descrever palavra-chave especifica o grupo de testes e o teste instrução especifica o teste específico. Se o valor retornado da função corresponder ao valor passado para ser, o teste passa.
Ao testar endpoints de API, você não estará chamando uma função, mas enviando uma solicitação usando o SuperTest ou outra biblioteca cliente HTTP.
Retornando ao endpoint GET, crie um novo arquivo chamado api.test.js. É aqui que você escreverá todos os testes de endpoint. Nomeando o arquivo de teste com um .teste infix garante que Jest o reconheça como um arquivo de teste.
Em api.test.js, importe supertest e defina o URL base assim:
const pedido = exigir("superteste")
const baseURL = "http://localhost: 3000"
Em seguida, crie o primeiro teste no bloco describe:
descrever("GET /todos", () => {
const novoTodo = {
Eu iria: criptografia.randomUUID(),
item: "Beber água",
concluído: falso,
}
Antes de tudo(assíncrono () => {
// configura o todo
aguardar solicitação (baseURL).post("/todo").send (novoTodo);
})
afinal(assíncrono () => {
aguardam solicitação (baseURL).delete(`/todo/${newTodo.id}`)
})
isto("deve retornar 200", assíncrono () => {
const resposta = aguardam request (baseURL).get("/todos");
Espero(resposta.statusCode).ser(200);
Espero(resposta.corpo.erro).ser(nulo);
});
isto("deveria devolver todos", assíncrono () => {
const resposta = aguardam request (baseURL).get("/todos");
esperar (resposta.corpo.data.comprimento >= 1).ser(verdadeiro);
});
});
Antes de executar os testes, você precisará definir as funções de configuração e desmontagem. Essas funções preencherão a matriz de tarefas com um item antes do teste e excluirão os dados fictícios após cada teste.
O código executado antes de todos os testes está na função beforeAll(). O código executado após todos os testes está na função afterAll().
Neste exemplo, você está simplesmente acessando os endpoints POST e DELETE para cada um. Em um aplicativo real, você provavelmente se conectaria a um banco de dados simulado contendo os dados de teste.
Neste teste, você primeiro fez uma solicitação ao endpoint GET /todos e comparou a resposta enviada de volta aos resultados esperados. Este conjunto de testes será aprovado se a resposta tiver um Código de status HTTP de 200, os dados não estão vazios e a mensagem de erro é nula.
Teste o endpoint POST /todo
Em index.js, crie o endpoint POST /todo:
app.post("/todo", (req, res) => {
tentar {
const { id, item, concluído } = req.body;
const novoTodo = {
Eu iria,
item,
concluído,
};
todos.Empurre(novoTodo);
Retornares.status(201).json({
dados: todos,
erro: nulo,
});
} truque (erro) {
Retornares.status(500).json({
dados: nulo,
erro: erro,
});
}
});
Neste teste, você precisará enviar os detalhes do todo no corpo da solicitação usando o método send().
request (baseURL).post("/todo").send (novoTodo)
A solicitação POST /todo deve retornar um código de status 201 e o array todos com o novo item adicionado ao final. Veja como pode ser o teste:
descrever("POST /todo", () => {
const novoTodo = {
// façam
}
afinal(assíncrono () => {
aguardam solicitação (baseURL).delete(`/todo/${newTodo.id}`)
})
isto("deve adicionar um item ao array todos", assíncrono () => {
const resposta = aguardam request (baseURL).post("/todo").send(newTodo);
const lastItem = response.body.data[response.body.data.length-1]
Espero(resposta.statusCode).ser(201);
Espero(último item.item).ser(novoTodo["item"]);
Espero(último item.concluído).ser(novoTodo["concluído"]);
});
});
Aqui, você está passando os dados de todo para o método send() como um argumento. A resposta deve ter um código de status 201 e também conter todos os itens de tarefas em um objeto de dados. Para testar se todo foi realmente criado, verifique se a última entrada nos todos retornados corresponde à que você enviou na solicitação.
O endpoint PUT /todos/:id deve retornar o item atualizado:
app.put("/todos/:id", (req, res) => {
tentar {
const id = req.params.id
const todo = todos.find((todo) => todo.id == id);
if(!todo) {
lançarnovoErro("Todo não encontrado")
}
todo.completo = req.corpo.completo;
Retornares.status(201).json({
dados: todo,
erro: nulo,
});
} truque (erro) {
Retornares.status(500).json({
dados: nulo,
erro: erro,
});
}
});
Teste a resposta da seguinte forma:
descrever("Atualizar uma tarefa", () => {
const novoTodo = {
// façam
}
Antes de tudo(assíncrono () => {
aguardar solicitação (baseURL).post("/todo").send (novoTodo);
})
afinal(assíncrono () => {
aguardam solicitação (baseURL).delete(`/todo/${newTodo.id}`)
})
isto("deve atualizar o item se existir", assíncrono () => {
const resposta = aguardam solicitação (baseURL).put(`/todos/${newTodo.id}`).mandar({
concluído: verdadeiro,
});
Espero(resposta.statusCode).ser(201);
Espero(resposta.corpo.dados.concluído).ser(verdadeiro);
});
});
O valor concluído no corpo da resposta deve ser verdadeiro. Lembre-se de incluir o id do item que deseja atualizar na URL.
Teste o terminal DELETE /todos/:id
Em index.js, crie o endpoint DELETE. Ele deve retornar os dados de tarefas sem o item excluído.
app.delete("/todos/:id", (req, res) => {
tentar {
const id = req.params.id
const todo = todos[0]
if (todo) {
todos.splice(Eu iria, 1)
}
Retornares.status(200).json({
dados: todos,
erro: nulo,
});
} truque (erro) {
Retornares.status(500).json({
dados: nulo,
erro: erro,
});
}
});
Para testar o endpoint, você pode verificar se o item excluído ainda existe nos dados retornados:
descrever("Excluir uma tarefa", () => {
const novoTodo = {
// façam
}
Antes de tudo(assíncrono () => {
aguardar solicitação (baseURL).post("/todo").send (novoTodo);
})
isto("deve excluir um item", assíncrono () => {
const resposta = aguardam solicitação (baseURL).delete(`/todos/${newTodo.id}`);
const todos = resposta.corpo.data
const existe = todos.find (todo => {
newTodo.id == todoId
})
esperar (existe).toBe(Indefinido)
});
});
Os dados retornados do endpoint DELETE não devem conter o item excluído. Como os itens retornados estão em uma matriz, você pode usar Array[id] para verificar se a API excluiu o item corretamente. O resultado deve ser falso.
Criando APIs REST
Neste artigo, você aprendeu como testar uma API Express Rest usando a API Jest. Você escreveu testes para as solicitações HTTP GET, PUT, POST e DELETE e viu como enviar dados para o endpoint na URL e na solicitação. Você deve ser capaz de aplicar esse conhecimento ao testar sua própria API Rest.