Pode ser um desafio testar os modelos do Mongoose porque você precisa escrever testes que não interfiram no seu banco de dados real. O pacote do servidor de memória MongoDB oferece uma solução simples. Ele permite que você armazene seus dados de teste na memória do aplicativo.
Neste tutorial, você criará um modelo Mongoose simples e escreverá testes usando Jest e o servidor de memória MongoDB.
O que é o servidor de memória MongoDB?
A última coisa que você quer é salvar dados falsos em seu banco de dados real, o que pode acontecer se você se conectar a ele durante o teste. Em vez disso, você pode optar por usar uma instância local separada do MongoDB para armazenar seus dados. Embora isso funcione, é inviável se seus testes forem executados na nuvem. Além disso, conectar e consultar um banco de dados real durante cada teste pode ficar caro.
Servidor de memória MongoDB, no entanto, ativa um servidor MongoDB real e permite que você armazene os dados de teste na memória. Isso o torna mais rápido do que usar um banco de dados MongoDB local, pois os dados não são gravados em um disco físico.
Criando o Modelo Mangusto
Os modelos Mongoose fornecem uma interface para interface com o banco de dados MongoDB. Para criá-los, você precisa compilá-los a partir de um esquema Mongoose, que define seu modelo de dados MongoDB. Este tutorial usará um esquema para um documento de tarefas pendentes. Ele conterá o título e os campos preenchidos.
Execute o seguinte comando no terminal para criar uma nova pasta e navegue até ela.
mkdir mongoose-model-test
cd teste-modelo-mangusto
Inicialize o npm com o seguinte comando:
npm init -y
o -y flag instrui o npm a gerar um arquivo package.json com valores padrão.
Execute este comando para instalar o mangusto pacote:
npm instalar mangusto
Crie um novo arquivo chamado todo.model.js e defina o esquema de tarefas:
const mangusto = exigir("mangusto")
const { Esquema } = mangusto
const TodoSchema = novo Esquema({
item: {
modelo: Corda,
requeridos: verdadeiro
},
concluído: {
modelo: boleano,
requeridos: verdadeiro
}
})
No final deste arquivo, crie e exporte o modelo de tarefas:
módulo.exportações = mongoose.model("Todo", TodoSchema)
Planejando os Testes
Ao escrever testes, você deseja planejar o que testará com antecedência. Isso garante que você esteja testando todas as funcionalidades do seu modelo.
A partir do modelo Mongoose que criamos, o todo deve conter um item do tipo String e um campo preenchido do tipo Boolean. Ambos os campos são obrigatórios. Isso significa que, no mínimo, nosso teste deve garantir:
- Os itens válidos são salvos com sucesso no banco de dados.
- Itens sem campos obrigatórios não são salvos.
- Itens com campos de tipo inválido não são salvos.
Vamos escrever esses testes em um bloco de teste, pois eles estão relacionados. No Jest, você define este bloco de teste usando o descrever função. Por exemplo:
descrever('Todo teste de modelo', () => {
// Seus testes vão aqui
}
Configurando o banco de dados
Para configurar um servidor de memória MongoDB, você criará uma nova instância do servidor de memória Mongo e se conectará ao Mongoose. Você também criará funções que serão responsáveis por descartar todas as coleções no banco de dados e desconectar da instância do servidor de memória Mongo.
Execute o seguinte comando para instalar servidor de memória mongodb.
npm instalar mongodb-memória-servidor
Crie um novo arquivo chamado setuptestdb.js e importe o mongoose e o servidor de memória mongodb.
const mangusto = exigir("mangusto");
const { MongoMemoryServer } = exigir("mongodb-servidor de memória");
Em seguida, crie uma função connectDB(). Essa função cria uma nova instância do servidor de memória Mongo e se conecta ao Mongoose. Você o executará antes de todos os testes para se conectar ao banco de dados de teste.
deixar mongo = nulo;
const connectDB = assíncrono () => {
mongo = aguardam MongoMemoryServer.create();
const uri = mongo.getUri();
aguardam mangusto.connect (uri, {
useNewUrlParser: verdadeiro,
useUnifiedTopology: verdadeiro,
});
};
Crie uma função dropDB() adicionando o código a seguir. Essa função descarta o banco de dados, fecha a conexão do Mongoose e interrompe a instância do servidor de memória do Mongo. Você executará esta função depois que todos os testes terminarem de ser executados.
const dropDB = assíncrono () => {
if (mongo) {
aguardammangusto.conexão.dropDatabase();
aguardammangusto.conexão.perto();
aguardam mongo.stop();
}
};
A última função que você criará é chamada dropCollections(). Ele descarta todas as coleções de Mongoose criadas. Você irá executá-lo após cada teste.
const dropCollections = assíncrono () => {
if (mongo) {
const coleções = aguardam mangusto.conexão.db.coleções();
por (deixar coleção do coleções) {
aguardam coleção.remover();
}
}
};
Finalmente, exporte as funções conenctDB(), dropDB() e dropCollections().
módulo.exportações = { connectDB, dropDB, dropCollections}
Escrevendo os testes
Como mencionado, você usará o Jest para escrever os testes. Execute o seguinte comando para instalar o jest.
npm instalar brincadeira
No pacote.json arquivo, configure jest. Substitua o bloco "scripts" existente pelo seguinte:
"roteiros": {
"teste": "jest --runInBand --detectOpenHandles"
},
"brincadeira": {
"ambiente de teste": "nó"
},
Crie um novo arquivo chamado todo.model.test.js e importe a biblioteca mangusto, o modelo todo e as funções conenctDB(), dropDB() e dropCollections():
const mangusto = exigir("mangusto");
const { connectDB, dropDB, dropCollections } = exigir("./setupdb");
const Tudo = exigir("./todo.model");
Você precisa executar a função connectDB() antes de todos os testes serem executados. Com Jest, você pode usar o método beforeAll().
Você também precisa executar funções de limpeza. Após cada teste, execute a função dropCollections() e a função dropDB() após todos os testes. Você não precisa fazer isso manualmente e pode usar os métodos afterEach() e afterAll() do Jest.
Adicione o seguinte código ao arquivo todo.model.test.js para configurar e limpar o banco de dados.
Antes de tudo(assíncrono () => {
aguardam conectarDB();
});afinal(assíncrono () => {
aguardam dropDB();
});
após cada(assíncrono () => {
aguardam dropCollections();
});
Agora você está pronto para criar os testes.
O primeiro teste verificará se o item de tarefas foi inserido com sucesso no banco de dados. Ele verificará se o ID do objeto está presente no criado para e se os dados nele contidos correspondem ao que você enviou ao banco de dados.
Crie um bloco de descrição e adicione o código a seguir.
descrever("Todo Modelo", () => {
isto("deve criar um item de tarefas com sucesso", assíncrono () => {
deixar validTodo = {
item: "Lavar os pratos",
concluído: falso,
};
const novoTodo = aguardam Todo (válidoTodo);
aguardam newTodo.save();
Espero(novoTodo._Eu iria).a ser definida();
Espero(novoTodo.item).ser(validTodo.item);
Espero(novoTodo.concluído).ser(validTodo.concluído);
});
});
este cria um novo documento no banco de dados contendo os dados na variável validTodo. O objeto retornado é então validado em relação aos valores esperados. Para que esse teste seja aprovado, o valor retornado deve ter um ID de objeto. Além disso, os valores no item e nos campos preenchidos devem corresponder aos do objeto validTodo.
Além de testar o caso de uso normal, você também precisa testar um caso de uso com falha. Dos testes que planejamos, você precisa testar o modelo mangusto com um objeto todo, com um campo obrigatório ausente e um com tipo incorreto.
Adicione um segundo teste ao mesmo bloco de descrição, da seguinte maneira:
isto("deve falhar para o item de tarefas sem campos obrigatórios", assíncrono () => {
deixar invalidTodo = {
item: "Lavar os pratos",
};
tentar {
const novoTodo = novo Todo (invalidTodo);
aguardam newTodo.save();
} truque (erro) {
Espero(erro).toBeInstanceOf(mangusto.Erro.Erro de validação);
Espero(erro.erros.concluído).a ser definida();
}
});
O modelo Todo mongoose espera o item e os campos preenchidos. Deve gerar um erro se você tentar salvar um todo sem um desses campos. Este teste usa o bloco try…catch para capturar o erro lançado. O teste espera que os erros sejam um erro de validação do mangusto e resultem do campo preenchido ausente.
Para testar se o modelo gera um erro se você usar valores do tipo errado, adicione o seguinte código ao bloco describe.
isto("deve falhar para o item de tarefas com campos de tipo errado", assíncrono () => {
deixar invalidTodo = {
item: "Lavar os pratos",
concluído: "Falso"
};
tentar {
const novoTodo = novo Todo (invalidTodo);
aguardam newTodo.save();
} truque (erro) {
Espero(erro).toBeInstanceOf(mangusto.Erro.Erro de validação);
Espero(erro.erros.concluído).a ser definida();
}
});
Observe que o valor do campo preenchido é uma string em vez de um booleano. O teste espera que um erro de validação seja gerado, pois o modelo espera um valor booleano.
MongoMemoryServer e Jest formam uma ótima equipe
O pacote npm mongo-memory-server fornece uma solução fácil para testar modelos Mongoose. Você pode armazenar dados fictícios na memória sem tocar no banco de dados do seu aplicativo.
Você pode usar MongoMemoryServer com Jest para escrever testes para modelos Mongoose. Observe que ele não abrange todos os testes possíveis que você pode escrever para seus modelos. Esses testes dependerão do seu esquema.