O serviço de teste no módulo de retornos angulares não está definido

127

Estou tentando executar o teste de unidade de serviço padrão no meu projeto (tirado do projeto Angular Seed no GitHub), mas continuo recebendo o erro "módulo não está definido".

Li que poderia ter algo a ver com a ordem dos arquivos JavaScript referenciados , mas não consigo fazê-lo funcionar, por isso espero que um de vocês possa ajudar.

Minha configuração para o teste é assim:

basePath = '../';

arquivos = [
'public / javascripts / lib / jquery-1.8.2.js',
'public / javascripts / lib / angular.js',
'public / javascripts / lib / angular- .js',
'public / app.js ',
' public / controllers /
.js ',
' public / directives.js ',
' public / filters.js ',
' public / services.js ',
JASMINE,
JASMINE_ADAPTER,
' public / javascripts / lib / angular-mocks. js ',
' test / unit / *. js '];

autoWatch = true;

navegadores = ['Chrome'];

junitReporter = {outputFile: 'test_out / unit.xml', conjunto: 'unit'};

O serviço é semelhante ao seguinte:

angular.module('myApp.services', []).
  value('version', '0.1');

O teste é assim:

'use strict';

describe('service', function() {
  beforeEach(module('myApp.services'));


  describe('version', function() {
    it('should return current version', inject(function(version) {
      expect(version).toEqual('0.1');
    }));
  });
});

E o erro ao executar o teste através do testacular é o seguinte:

ReferenceError: o módulo não está definido

DOFs
fonte
2
você pode compartilhar seu projeto em algum lugar? Eu posso ajudar. Você tentou ativar o nível DEBUG para testacular para ver quais arquivos são realmente carregados com base na sua configuração? Por enquanto, a parte suspeita é esse padrão: public / javascripts / lib / angular-.js - com o que deve corresponder?
pkozlowski.opensource
@ JohnDoe Obrigado por ter funcionado. Se você adicionar uma resposta, marcarei como resolvida. O motivo foi que eu estava acompanhando o projeto inicial, que fez dessa maneira e que funcionou. Não sei se é porque era uma versão anterior.
DOFs
@Dofs "'public / javascripts / lib / angular-.js'," e "'public / controllers / .js'" são erros de digitação?
Ryan O'Neill
@ RyanO'Neill desculpe, sim, este foi um erro de digitação.
Dofs 15/05

Respostas:

260

Está faltando o arquivo angular-mocks.js .

John Doe
fonte
8
Observe que angular.modulee nãoangular.mock.module são os mesmos. A função é um alias para . Veja esta resposta para mais. window.moduleangular.mock.module
precisa saber é o seguinte
Como diz o comentário anterior, angular.module não é um alias para angular.mock.module.
Filippo De Luca
7
Essa resposta seria muito mais útil se oferecesse algum conselho sobre como fornecer o referido arquivo. Eu precisava instalar o Bower, depois o NgMocks.
Isherwood
4
A resposta fornece apenas parte da solução. Este é realmente um comentário e não uma explicação. Algumas das respostas abaixo são muito mais detalhadas.
Gerome Bochmann
1
Para os iniciantes, você precisa adicionar uma referência ao angular-mocksno karma.conf.jsarquivo e executar os testes através de Karma, não Jasmine. Dessa forma, quando o Karma é executado, ele pega as angular-mocksextensões e as incorpora ao ambiente.
Lucas
41

Eu tive o mesmo problema e entendi por que não estava funcionando: O javascript jasmine.js deve ser referenciado antes do arquivo angular-mocks.js. De fato, o angular-mocks.js verifica se o Jasmine está carregado, e somente se estiver adicionará a função do módulo à janela.

Aqui está um extrato do código Angular Mocks:

(Edite após os poucos comentários sobre 'hacking' que tive abaixo: este é apenas um extrato do código, não é algo que você precise escrever, já está lá!)

window.jasmine && (function(window) {

[...]

  window.module = angular.mock.module = function() {
    var moduleFns = Array.prototype.slice.call(arguments, 0);
    return isSpecRunning() ? workFn() : workFn;
    /////////////////////
    [...]
  };

Em poucas palavras: Basta referenciar o seu jasmine.js antes de angular-mocks.js e pronto.

Antoine Jaussoin
fonte
Isso também pode ser resolvido, garantindo que os arquivos javascript jasmine sejam carregados antes das zombarias angulares. Solução mais limpa do que fazer alterações hacky para fazer as coisas funcionarem.
Foomip 13/05
Quem sugeriu fazer alterações hacky?
21414 Stephen
Você essencialmente inseriu um hack no aplicativo para garantir que as coisas sejam carregadas da maneira correta - e eu não quis dizer hack de maneira ruim (não há nada errado com a maneira como você escreveu esse trecho de código), mas o que acontece quando um atualizar para jasmim ou outra coisa faz com que esse snippet quebre ou que não funcione mais como o esperado? Pode ou não acontecer, mas isso é uma responsabilidade no seu código agora que pode ser evitada, você não acha?
Foomip 19/05/2014
@ foomip: Não sei ao que você está se referindo, mas se é sobre o meu código acima, isso não foi escrito por mim, estou apenas citando-o para explicar o problema. O código faz parte de zombarias angulares. A correção é simplesmente uma questão de referenciar um arquivo antes do outro.
Antoine Jaussoin
36

A window.modulefunção vem em angular-mocks.js e é uma abreviação de angular.mock.module. Conforme mencionado nos documentos , a modulefunção funciona apenas com o Jasmine.

Usando o Testacular , o seguinte exemplo de arquivo de configuração será carregado angular-mocks.js.

/** example testacular.conf.js */

basePath = '../';
files = [
  JASMINE,
  JASMINE_ADAPTER,
  'path/to/angular.js',
  'path/to/angular-mocks.js',   // for angular.mock.module and inject.
  'src/js/**/*.js',             // application sources
  'test/unit/**/*.spec.js'      // specs
];
autoWatch = true;
browsers = ['Chrome'];

E, como sugerido em outro lugar, você pode executar o Testacular com o log de depuração para ver quais scripts estão carregados (você também pode ver o mesmo no inspetor):

testacular --log-level debug start config/testacular.conf.js

Os angular.mock.injectdocumentos incluem um exemplo bastante completo.

Tim Schaub
fonte
Talvez interessante notar que moduleagora também trabalha com mocha
Robin-Hoodie
11

Usamos 'module' sem 'angular' em nossos testes de unidade e funciona bem.

CoffeeScript:

describe 'DiscussionServicesSpec', ->
    beforeEach module 'DiscussionServices'
    beforeEach inject ... etc.

que compila para

JavaScript:

describe('DiscussionServices', function() {
    beforeEach(module('DiscussionServices'));
    beforeEach(inject(function ... etc.

A única vez em que vejo algo como o erro que você descreveu é que, no arquivo testacular.conf.js, o arquivo angular-mocks.js não está listado na seção de arquivos antes das especificações que tentam usar o 'módulo'. Se eu colocá-lo após meus testes na lista de 'arquivos', recebo

ReferenceError: Can't find variable: module

(Nossos testes estão sendo executados pelo PhantomJS)

Ryan O'Neill
fonte
2
A coisa a concluir é que zombarias angulares são um requisito.
Adrien
3

Eu incluí angular-mocks.js na minha configuração de karma, mas ainda estava recebendo o erro. Acontece que a ordem é importante na matriz de arquivos. (duh) Assim como na cabeça de um documento html, se um script chama angular antes de ser definido, e ocorre um erro. Então, eu apenas precisei incluir meu app.js após angular.js e angular-mocks.js.

Erik
fonte
0

Se você estiver usando o Yeoman e seu gerador angular, provavelmente receberá esse erro. Especialmente quando você faz o Tutorial (._.),
Eu o corrigi, copiando o arquivo angular-mocks.js, do diretório bower_components / angular-mocks para o diretório test / mock. Claro que você precisa ter certeza de que o seu arquivo karma.conf.js está configurado corretamente.
Saudações!

alxU
fonte
0

Eu tive esse mesmo problema quando estava fazendo algo parecido var module = angular.module('my',[]). Eu precisava ter certeza de que estava cercado pelo IIFE

Jackie
fonte