Atualizado: 02/01/2025

Mocha - Node.js

O teste é uma parte importante do desenvolvimento em Node.js. Para facilitar esse processo, é recomendável utilizar frameworks existentes que simplificam os testes. Um desses frameworks é o Mocha. Para mais detalhes sobre o Mocha, você pode visitar a página oficial Mochajs. Aqui, vamos explorar alguns aspectos básicos de como trabalhar com ele.

Primeiro, vamos definir um novo arquivo package.json na pasta do projeto com o seguinte conteúdo:

{
  "name": "testapp",
  "version": "1.0.0"
}

Em seguida, adicionamos o pacote Mocha ao projeto usando o seguinte comando:

npm install mocha --save-dev

Como o framework Mocha é usado apenas para testar a aplicação, ele é adicionado na seção devDependencies do arquivo package.json com o comando --save-dev.

Para testar, vamos definir um módulo simples. Adicionamos ao projeto um arquivo operations.js com o seguinte conteúdo:

module.exports.multiply = function(x, y) {
  return x * y;
}

Aqui, definimos uma função que multiplica dois números.

Para testar este módulo, adicionamos ao projeto um novo arquivo operations.test.js:

const operations = require("./operations");

it("should multiply two numbers", function() {
    const expectedResult = 15;
    const result = operations.multiply(3, 5);
    if (result !== expectedResult) {
        throw new Error(`Expected ${expectedResult}, but got ${result}`);
    }
});

Vamos analisar este teste. Para testar o resultado, usamos a função it(), fornecida pelo framework Mocha. Esta função aceita dois parâmetros: uma descrição textual da ação a ser testada, para identificá-la, e a função de teste em si.

Por exemplo, precisamos verificar a função multiply() definida acima, que multiplica dois números. Para isso, passamos dois números para esta função e comparamos o resultado com o esperado. Se o resultado não corresponder ao valor esperado, é lançado um erro.

Para simplificar a execução dos testes, modificamos o arquivo package.json da seguinte forma:

{
  "name": "testapp",
  "version": "1.0.0",
  "scripts": {
    "test": "mocha *.test.js"
  },
  "devDependencies": {
    "mocha": "^10.7.0"
  }
}

Aqui, adicionamos a seção "scripts", onde definimos o comando "test". Este comando executa "mocha *.test.js", que inicia os testes usando Mocha, passando ao framework todos os arquivos que terminam com ".test.js".

Se tivermos apenas um arquivo de teste, poderíamos especificar o nome completo do arquivo, como mocha operations.test.js.

Em seguida, no terminal, vamos para a pasta do projeto e executamos o comando npm test:

c:\app> npm test

> testapp@1.0.0 test
> mocha *.test.js

✔ should multiply two numbers

1 passing (5ms)

Aqui, o console indica que o teste foi bem-sucedido.

No entanto, se alterarmos o código do teste para:

const operations = require("./operations");

it("should multiply two numbers", function() {
    const expectedResult = 16;
    const result = operations.multiply(3, 5);
    if (result !== expectedResult) {
        throw new Error(`Expected ${expectedResult}, but got ${result}`);
    }
});

O teste não será bem-sucedido, pois o resultado - 15 não é igual ao resultado esperado - 16. E o console notificará sobre isso ao executar o teste novamente:

c:\app> npm test

> testapp@1.0.0 test
> mocha *.test.js

1) should multiply two numbers

0 passing (6ms)
1 failing

1) should multiply two numbers:
    Error: Expected 16, but got 15
    at Context.<anonymous> (operations.test.js:8:9)
    at process.processImmediate (node:internal/timers:478:21)

Da mesma forma, podemos definir outros testes. Por exemplo, alteramos o arquivo do módulo operations.js:

module.exports.multiply = function(x, y) { return x * y; }
module.exports.add = function(x, y) { return x + y; }

Agora, foi adicionada uma função para somar números. Vamos testá-la em operations.test.js:

const operations = require("./operations");

it("should multiply two numbers", function() {
    const expectedResult = 15;
    const result = operations.multiply(3, 5);
    if (result !== expectedResult) {
        throw new Error(`Expected ${expectedResult}, but got ${result}`);
    }
});
it("should add two numbers", function() {
    const expectedResult = 16;
    const result = operations.add(9, 7);
    if (result !== expectedResult) {
        throw new Error(`Expected ${expectedResult}, but got ${result}`);
    }
});

Executamos o teste:

c:\app> npm test

> testapp@1.0.0 test
> mocha *.test.js

✔ should multiply two numbers
✔ should add two numbers

2 passing (5ms)

Testando Funções Assíncronas

Testar funções assíncronas é um pouco diferente. Vamos definir uma função assíncrona no módulo operations.js:

module.exports.multiply = function(x, y) {
  return x * y;
}
module.exports.add = function(x, y) {
  return x + y;
}

module.exports.multiplyAsync = function(a, b, callback) {
  setTimeout(function() {
      callback(a * b);
  }, 1000);
}

Vamos testar esta função em operations.test.js:

const operations = require("./operations");

it("should multiply two numbers", function() {
    const expectedResult = 15;
    const result = operations.multiply(3, 5);
    if (result !== expectedResult) {
        throw new Error(`Expected ${expectedResult}, but got ${result}`);
    }
});
it("should add two numbers", function() {
    const expectedResult = 16;
    const result = operations.add(9, 7);
    if (result !== expectedResult) {
        throw new Error(`Expected ${expectedResult}, but got ${result}`);
    }
});

it("should async multiply two numbers", function(done) {
    const expectedResult = 12;
    operations.multiplyAsync(4, 3, function(result) {
        if (result !== expectedResult) {
            throw new Error(`Expected ${expectedResult}, but got ${result}`);
        }
        done();
    });
});

A particularidade de testar funções assíncronas é que, para garantir que elas terminem antes de o teste ser concluído, passamos uma função done() para a função de teste. Precisamos chamar esta função ao final do teste. Dessa forma, o Mocha pode controlar a execução do teste corretamente.

Executamos o teste:

c:\app> npm test

> testapp@1.0.0 test
> mocha *.test.js

✔ should multiply two numbers
✔ should add two numbers
✔ should async multiply two numbers (1002ms)

3 passing (1s)

Se não passarmos a função done para a função de teste, o teste terminará antes que a função assíncrona seja concluída.

Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com