Estou tentando descobrir como testar funções internas (ou seja, não exportadas) em nodejs (de preferência com mocha ou jasmim). E eu não tenho ideia!
Digamos que eu tenho um módulo como esse:
function exported(i) {
return notExported(i) + 1;
}
function notExported(i) {
return i*2;
}
exports.exported = exported;
E o seguinte teste (mocha):
var assert = require('assert'),
test = require('../modules/core/test');
describe('test', function(){
describe('#exported(i)', function(){
it('should return (i*2)+1 for any given i', function(){
assert.equal(3, test.exported(1));
assert.equal(5, test.exported(2));
});
});
});
Existe alguma maneira de testar a notExported
função da unidade sem realmente exportá-la, pois ela não deve ser exposta?
node.js
unit-testing
jasmine
mocha
xavier.seignard
fonte
fonte
Respostas:
O módulo de religação é definitivamente a resposta.
Aqui está o meu código para acessar uma função não exportada e testá-la usando o Mocha.
application.js:
test.js:
fonte
Cannot find module '../../package' from 'node.js'
. você viu isso?O truque é definir a
NODE_ENV
variável de ambiente para algo comotest
e exportá-la condicionalmente.Supondo que você não instalou o mocha globalmente, você pode ter um Makefile na raiz do diretório do seu aplicativo que contém o seguinte:
Este arquivo make configura o NODE_ENV antes de executar o mocha. Você pode executar seus testes de mocha
make test
na linha de comando.Agora, você pode exportar condicionalmente sua função que normalmente não é exportada apenas quando os testes do mocha estão em execução:
A outra resposta sugeriu o uso de um módulo vm para avaliar o arquivo, mas isso não funciona e gera um erro informando que as exportações não estão definidas.
fonte
EDITAR:
Carregar um módulo usando
vm
pode causar comportamento inesperado (por exemplo, oinstanceof
operador não trabalha mais com objetos criados nesse módulo porque os protótipos globais são diferentes daqueles usados no módulo carregado normalmente com elerequire
). Não uso mais a técnica abaixo e, em vez disso, uso o módulo de religação . Funciona maravilhosamente. Aqui está a minha resposta original:Elaborando a resposta do srosh ...
Parece um pouco hacky, mas escrevi um módulo "test_utils.js" simples que deve permitir que você faça o que deseja sem ter exportações condicionais em seus módulos de aplicativo:
Há mais algumas coisas incluídas no
module
objeto global de um módulo de nó que também podem precisar ir aocontext
objeto acima, mas esse é o conjunto mínimo necessário para que ele funcione.Aqui está um exemplo usando o mocha BDD:
fonte
rewire
?Trabalhando com Jasmine, tentei ir mais fundo com a solução proposta por Anthony Mayfield , baseada em religar .
Eu implementei a seguinte função ( Cuidado : ainda não foi completamente testado, apenas compartilhado como uma estratégia possível) :
Com uma função como essa, você pode espionar os métodos de objetos não exportados e funções de nível superior não exportados, da seguinte maneira:
Então você pode definir expectativas como estas:
fonte
você pode criar um novo contexto usando o módulo vm e avaliar o arquivo js nele, como o repl faz. então você tem acesso a tudo o que declara.
fonte
Eu encontrei uma maneira bastante simples que permite testar, espionar e zombar dessas funções internas de dentro dos testes:
Digamos que temos um módulo de nó como este:
Se agora queremos teste e de espionagem e simulada
myInternalFn
embora não exportá-lo na produção , temos de melhorar o arquivo como este:Agora você pode testar, espionar e zombar em
myInternalFn
qualquer lugar em que o use comotestable.myInternalFn
na produção e não seja exportado .fonte
Essa prática não é recomendada, mas se você não puder usar
rewire
como sugerido por @Antoine, sempre poderá ler o arquivo e usá-loeval()
.Achei isso útil durante o teste de unidade de arquivos JS do lado do cliente para um sistema legado.
Os arquivos JS iria criar uma série de variáveis globais sob
window
sem qualquerrequire(...)
emodule.exports
instrução (não havia empacotador de módulo como o Webpack ou o Browserify disponíveis para remover essas instruções de qualquer maneira).Em vez de refatorar toda a base de código, isso nos permitiu integrar testes de unidade em nosso JS do lado do cliente.
fonte