Eu tenho um módulo AMD que quero testar, mas quero zombar de suas dependências em vez de carregar as dependências reais. Estou usando requirejs, e o código do meu módulo é algo como isto:
define(['hurp', 'durp'], function(Hurp, Durp) {
return {
foo: function () {
console.log(Hurp.beans)
},
bar: function () {
console.log(Durp.beans)
}
}
}
Como posso zombar hurp
e durp
poder efetivamente testar a unidade?
javascript
unit-testing
mocking
requirejs
jergason
fonte
fonte
define
função. Existem algumas opções diferentes. Vou postar uma resposta na esperança de que seja útil.Respostas:
Então, depois de ler este post, criei uma solução que usa a função de configuração requirejs para criar um novo contexto para o seu teste, onde você pode simplesmente zombar de suas dependências:
Portanto, ele cria um novo contexto em que as definições
Hurp
eDurp
serão definidas pelos objetos que você passou para a função. O Math.random para o nome é talvez um pouco sujo, mas funciona. Porque, se você tiver vários testes, precisará criar um novo contexto para cada conjunto para evitar a reutilização de suas simulações ou carregá-las quando desejar o módulo real requirejs.No seu caso, seria assim:
Então, eu estou usando essa abordagem na produção por um tempo e é realmente robusta.
fonte
createContext
função. Portanto, no seu caso, se você passar apenas{hurp: 'hurp'}
para a função, odurp
arquivo será carregado como uma dependência normal.convém verificar a nova lib do Squire.js
dos documentos:
O Squire.js é um injetor de dependência para usuários do Require.js, para facilitar as dependências de zombaria!
fonte
Eu encontrei três soluções diferentes para esse problema, nenhuma delas agradável.
Definindo dependências em linha
Fugly. Você precisa desordenar seus testes com muitos clichês da AMD.
Carregando dependências simuladas de caminhos diferentes
Isso envolve o uso de um arquivo config.js separado para definir caminhos para cada uma das dependências que apontam para zombarias, em vez das dependências originais. Isso também é feio, exigindo a criação de toneladas de arquivos de teste e arquivos de configurações.
Fake It In Node
Esta é a minha solução atual, mas ainda é terrível.
Você cria sua própria
define
função para fornecer suas próprias simulações ao módulo e colocar seus testes no retorno de chamada. Então você éeval
o módulo para executar seus testes, da seguinte forma:Esta é a minha solução preferida. Parece um pouco de mágica, mas tem alguns benefícios.
eval
raiva e imagina Crockford explodindo de raiva.Ainda tem algumas desvantagens, obviamente.
define
todos os testes, pois é aí que seus testes realmente são executados.Estou trabalhando em um executor de teste para fornecer uma sintaxe melhor para esse tipo de coisa, mas ainda não tenho uma boa solução para o problema 1.
Conclusão
Zombar deps em requirejs é uma droga. Eu encontrei uma maneira que funciona, mas ainda não estou muito feliz com isso. Entre em contato se tiver alguma idéia melhor.
fonte
Existe uma
config.map
opção http://requirejs.org/docs/api.html#config-map .Sobre como usá-lo:
Configure o RequireJS de forma exponencial
Nesse caso, para código normal e de teste, você pode usar o
foo
módulo, que será uma referência real do módulo e o stub adequadamente.fonte
Você pode usar o testr.js para simular dependências. Você pode configurar o testr para carregar as dependências simuladas em vez das dependentes originais. Aqui está um exemplo de uso:
Confira também: http://cyberasylum.janithw.com/mocking-requirejs-dependencies-for-unit-testing/
fonte
Esta resposta é baseada na resposta de Andreas Köberle .
Não foi tão fácil para mim implementar e entender sua solução, por isso vou explicar com mais detalhes como ela funciona e algumas armadilhas a serem evitadas, esperando que ajude futuros visitantes.
Então, primeiro de tudo a configuração:
eu estou usando Karma como executor de teste e MochaJs como estrutura de teste.
Usando algo como Squire não funcionou para mim, por algum motivo, quando o usei, a estrutura de teste gerou erros:
RequireJs tem a possibilidade de mapear IDs de módulo para outros IDs de módulo. Também permite criar uma
require
função que usa uma configuração diferente da globalrequire
.Esses recursos são cruciais para que esta solução funcione.
Aqui está a minha versão do código simulado, incluindo (muitos) comentários (espero que seja compreensível). Coloquei-o dentro de um módulo, para que os testes possam exigir com facilidade.
o maior armadilha que encontrei, que literalmente me custou horas, foi criar a configuração do RequireJs. Tentei copiá-lo (em profundidade) e apenas substituí as propriedades necessárias (como contexto ou mapa). Isso não funciona! Apenas copie o
baseUrl
, isso funciona bem.Uso
Para usá-lo, exija-o em seu teste, crie as simulações e depois passe-o para
createMockRequire
. Por exemplo:E aqui um exemplo de um arquivo de teste completo :
fonte
se você quiser fazer alguns testes js simples que isolam uma unidade, basta usar este snippet:
fonte