Estou usando o mocha para fazer o teste de unidade de um aplicativo escrito para node.js
Gostaria de saber se é possível realizar funções de teste de unidade que não foram exportadas em um módulo.
Exemplo:
Eu tenho muitas funções definidas assim em foobar.js
function private_foobar1(){
...
}
function private_foobar2(){
...
}
e algumas funções exportadas como públicas:
exports.public_foobar3 = function(){
...
}
O caso de teste está estruturado da seguinte maneira:
describe("private_foobar1", function() {
it("should do stuff", function(done) {
var stuff = foobar.private_foobar1(filter);
should(stuff).be.ok;
should(stuff).....
Obviamente, isso não funciona, pois private_foobar1
não é exportado.
Qual é a maneira correta de testar métodos particulares? O mocha possui alguns métodos internos para fazer isso?
Respostas:
Se a função não for exportada pelo módulo, ela não poderá ser chamada pelo código de teste fora do módulo. Isso se deve à maneira como o JavaScript funciona, e o Mocha não pode contornar isso por si só.
Nos poucos casos em que determinei que testar uma função privada é a coisa certa a fazer, o que fiz foi definir alguma variável de ambiente que meu módulo verifica para determinar se está sendo executado em uma configuração de teste ou não. Se ele for executado na configuração de teste, ele exporta funções adicionais que eu posso chamar durante o teste.
A palavra "ambiente" é pouco usada aqui. Pode significar verificação
process.env
ou outra coisa que possa se comunicar com o módulo "você está sendo testado agora". As instâncias em que tive que fazer isso estavam em um ambiente RequireJS e useimodule.config
para esse fim.fonte
SyntaxError: 'import' and 'export' may only appear at the top level
import
,export
dentro de um bloco. Eventualmente, você poderá realizar esse tipo de coisa no ES6 com o carregador do sistema. Uma maneira de contornar isso agora é usarmodule.exports = process.env.NODE_ENV === 'production' ? require('prod.js') : require('dev.js')
e armazenar suas diferenças de código es6 nesses arquivos.Confira o módulo de religação . Ele permite que você obtenha (e manipule) variáveis e funções privadas dentro de um módulo.
Portanto, no seu caso, o uso seria algo como:
fonte
Cannot find module '../../package' from 'node.js'
. Alguém familiarizado com isso?.ts
,typescript
eu corro usandots-node
@cluAqui está um fluxo de trabalho realmente bom para testar seus métodos particulares, explicados por Philip Walton, engenheiro do Google em seu blog.
Princípio
_
por exemploEm seguida, use uma tarefa de compilação ou seu próprio sistema de compilação (por exemplo, código de faixa de resmungo) para retirar esse bloco para compilações de produção.
Suas construções de testes têm acesso à sua API privada e suas construções de produção não.
Snippet
Escreva seu código como este:
E suas tarefas difíceis assim
Mais profundo
Em um artigo posterior , ele explica o "porquê" de "testar métodos privados"
fonte
Se você preferir manter as coisas simples, exporte também os membros privados, mas claramente separados da API pública com alguma convenção, por exemplo, prefixe-os com um
_
ou aninhe-os em um único objeto privado .fonte
Criei um pacote npm para esse fim que você pode achar útil: require-from
Basicamente, você expõe métodos não públicos por:
nota:
testExports
pode ser qualquer nome válido que você queira, exceto éexports
claro.E de outro módulo:
fonte
requireFrom
com os parâmetros corretos.) Além disso, se o módulotextExports
é carregado por umarequire
chamada antes de carregá-requireFrom
la,requireFrom
retornaráundefined
. (Acabei de testar.) Embora muitas vezes seja possível controlar a ordem de carga dos módulos, nem sempre é prático. (Como evidenciado por algumas perguntas do Mocha sobre SO). Essa solução também geralmente não funciona com módulos do tipo AMD. (Eu carrego módulos da AMD no Node diariamente para teste.) #Eu adicionei uma função extra com o nome Internal () e retorno todas as funções privadas a partir daí. Essa função Internal () é exportada. Exemplo:
Você pode chamar as funções internas assim:
Eu gosto mais desta solução porque:
fonte
Eu segui a resposta @barwin e verifiquei como os testes de unidade podem ser feitos com o módulo de religação . Posso confirmar que esta solução simplesmente funciona.
O módulo deve ser exigido em duas partes - pública e privada. Para funções públicas, você pode fazer isso da maneira padrão:
Para escopo privado:
Para saber mais sobre o assunto, criei um exemplo de trabalho com teste completo do módulo, o teste inclui escopo público e privado.
Para obter mais informações, recomendamos que você verifique o artigo ( https://medium.com/@macsikora/how-to-test-private-functions-of-es6-module-fb8c1345b25f ) descrevendo completamente o assunto, incluindo exemplos de código.
fonte
Sei que essa não é necessariamente a resposta que você está procurando, mas o que descobri é que, na maioria das vezes, se uma função privada vale a pena testar, vale a pena estar em seu próprio arquivo.
Por exemplo, em vez de ter métodos privados no mesmo arquivo que os públicos, como este ...
src / thing / PublicInterface.js
... você divide assim:
src / thing / PublicInterface.js
src / coisa / interno / helper1.js
src / coisa / interno / helper2.js
Dessa forma, você pode facilmente testar
helper1
ehelper2
como está, sem usar o Rewire e outras "mágicas" (que, eu descobri, têm seus próprios pontos problemáticos durante a depuração, ou quando você tenta avançar para o TypeScript, sem mencionar os mais pobres compreensibilidade para novos colegas). E eles estarem em uma subpasta chamadainternal
, ou algo assim, ajudará a evitar o uso acidental deles em locais indesejados.PS: Outro problema comum com os métodos "privados" é que se pretende testar
publicMethod1
epublicMethod2
e zombar dos ajudantes, mais uma vez, você normalmente precisa de algo como Rewire para fazer isso. No entanto, se eles estiverem em arquivos separados, é possível usar o Proxyquire para fazê-lo, o que, diferentemente do Rewire, não precisa de alterações no processo de compilação, é fácil de ler e depurar e funciona bem mesmo com o TypeScript.fonte
Para disponibilizar métodos particulares para teste, eu faço o seguinte:
fonte