Sinon para JavaScript (Node.js): guia completo com exemplos práticos
1. O que é e para que serve
Sinon.js é uma biblioteca poderosa para JavaScript que fornece dublês de teste autônomos: espiões (spies), stubs (stubs) e mocks (mocks). Ela não depende de nenhum framework de teste específico (Mocha, Jest, Jasmine, etc.) e pode ser usada com qualquer um deles. O principal objetivo do Sinon é isolar o código testado de dependências externas (banco de dados, API, sistema de arquivos, timers), permitindo verificar o comportamento das funções em um ambiente controlado.
Por que isso é necessário? Em aplicações reais, as funções frequentemente chamam outras funções, acessam serviços externos ou trabalham com operações assíncronas. Sem o Sinon, você não consegue verificar facilmente se uma função de callback foi chamada, com quais argumentos, quantas vezes, ou simular uma resposta do servidor. O Sinon resolve esses problemas de forma elegante e concisa, tornando os testes rápidos, confiáveis e previsíveis.
A biblioteca é especialmente popular no ecossistema Node.js, onde os testes unitários são essenciais. Ela permite testar funções sem fazer requisições HTTP reais, acessar o banco de dados ou esperar por timers. Isso acelera a execução dos testes em dezenas de vezes e os torna determinísticos.
2. Instalação
O Sinon é instalado via npm. Para Node.js, execute o comando:
npm install sinon --save-dev
Se você usa TypeScript, instale também os tipos:
npm install sinon @types/sinon --save-dev
Para usar no navegador, você pode incluir a versão CDN:
<script src="https://cdn.jsdelivr.net/npm/sinon@latest/pkg/sinon.js"></script>
Após a instalação, importe a biblioteca no seu arquivo de teste:
const sinon = require('sinon'); // CommonJS
// ou
import sinon from 'sinon'; // ES Modules
3. Início rápido — exemplo mínimo funcional
Vamos ver um exemplo simples: uma função que chama um callback com uma saudação. Queremos verificar se o callback foi chamado com o argumento correto.
const sinon = require('sinon');
// Função que estamos testando
function greet(name, callback) {
callback(`Olá, ${name}!`);
}
// Teste usando um espião (spy)
const callbackSpy = sinon.spy();
greet('Alice', callbackSpy);
console.log(callbackSpy.calledOnce); // true
console.log(callbackSpy.calledWith('Olá, Alice!')); // true
Este exemplo demonstra a ideia básica: criamos um espião, passamos para a função testada e depois verificamos como ele foi chamado. Em testes reais, você usará asserções do seu framework de teste.
4. Principais métodos/funções/classes
4.1. sinon.spy() — Espião (Spy)
Assinatura: sinon.spy([objeto], [método]) ou sinon.spy([funcao])
O que faz: Cria um espião que registra informações sobre as chamadas da função: número de chamadas, argumentos, contexto, valor retornado. Pode envolver uma função existente ou substituir um método de um objeto.
Exemplo:
const usuario = {
setNome: function(nome) { this.nome = nome; }
};
const spy = sinon.spy(usuario, 'setNome');
usuario.setNome('João');
console.log(spy.calledOnce); // true
console.log(spy.calledWith('João')); // true
console.log(spy.firstCall.args); // ['João']
spy.restore(); // obrigatório restaurar o método original
4.2. sinon.stub() — Stub (substituto)
Assinatura: sinon.stub([objeto], [método])
O que faz: Cria um substituto que substitui a função e permite pré-definir seu comportamento: retornar um valor específico, lançar uma exceção, chamar um callback, etc. Ideal para simular dependências externas.