Como faço para depurar um erro “[Object ErrorEvent] lançado” em meus testes de Karma / Jasmine?

108

Eu tenho vários testes com falha que apenas produzem [object ErrorEvent] thrown. Não vejo nada no console que me ajude a identificar o código ofensivo. Há algo que eu preciso fazer para rastreá-los?

[EDIT]: Estou executando o Karma v1.70, Jasmine v2.7.0

Darrell Brogdon
fonte
Você pode incluir mais do erro? Como várias linhas do erro antes e depois?
Kevin
2
[object ErrorEvent] throwné literalmente tudo o que diz. Não há nada antes ou depois.
Darrell Brogdon de
1
Por sorte, eu acabei de pegar esse problema literalmente na mesma hora em que você postou esta pergunta, acabou sendo uma tag de script "desonesta" (também pode ser um link css) que precisava ser removida (meu problema estava relacionado para CORS), ou no caso de css, apenas adicionei crossorigin = "anonymous". Verifique seu código para essas tags script / css, no meu caso, descobri que o problema foi causado por um componente totalmente diferente!
TheDude
você está no cli angular, não é? @DarrellBrogdon
kuncevic.dev
1
@TheDude Como você restringiu este script? Linha por linha? Ou houve algum processo de depuração que ajudou a restringir onde ele estava? Estou tendo o mesmo problema e a única informação que preciso continuar é a mensagem: Um erro foi lançado em afterAll. Se eu isolar o próprio teste mudando it()para fit(), mesmo que apenas aquele único teste esteja sendo executado, o erro ainda está sendo gerado. Alguma recomendação de depuração para este tipo de erro?
Cavaleiro de

Respostas:

121

Para sua informação: você pode encontrar o erro exato lançado apenas abrindo o console do DevTools quando seus testes estiverem em execução.

Como uma correção rápida, você pode tentar executar seus testes sem mapas de origem :

CLI v6.0.8 e superior
--source-map=false

CLI v6.0.x primeiras versões
--sourceMap=false

CLI v1.x
--sourcemaps=false

O atalho ng test -sm=falsetambém pode funcionar

Há um problema em aberto nesse https://github.com/angular/angular-cli/issues/7296

ATUALIZAÇÃO : Eu também tive esse problema, então migrei para o CLI mais recente e certifique-se de que todos os pacotes estão atualizados package.jsontambém. Reinstalei totalmente o, node_modulesentão agora o problema foi embora.

kuncevic.dev
fonte
3
isso funcionou para mim. Isso ajudou a revelar que o problema era com uma ligação de entrada indefinida.
JP Lew
10
Para angular-cli 6, --sourceMap=falseparece funcionar.
skermajo
1
solução típica de frente
Mcsky
1
Esta solução não funciona mais. Costumava, mas no 6.2.4 não
Mike,
3
Eu recebo Uncaught [Object Object] jogado em componentes aleatórios e em algumas execuções eu não recebo nada ...: SI odeio Angular Testing.
Gerardo Buenrostro González
51

Se sourcemap = false não ajudar, tente 1) abrir seu navegador executando os testes 2) clique no botão de depuração 3) abra o console

O erro estará aí

insira a descrição da imagem aqui

Victor Bredihin
fonte
8
Nem precisei clicar no botão de depuração. Apenas abrir o console do desenvolvedor funcionou para mim.
chris31389
Brilhante! Adicionei a opção de mapa de origem em todos os lugares, mas no final isso me deu a informação de que precisava
SkarXa
1
A --sourcemaps=falsecoisa não estava funcionando para mim, mas funcionou perfeitamente! Obrigado!
mrClean
Realmente não ajuda se o navegador fechar logo após o teste. Acho que vou escrever um monte de testes inúteis para manter a janela aberta, como uma espécie de homem das cavernas.
CoryCoolguy
24

Tente se você receber uma mensagem de erro mais descritiva executando o teste no terminal, como este:

ng test -sm=false

Em seu teste, você pode substituir

it('should...')

com

fit('should...') 

Agora, apenas os testes precedidos por ajuste serão executados. Para deixar o navegador aberto após executar o teste, execute o teste assim:

ng test -sm=false --single-run false

Pessoalmente, encontrei esse erro duas vezes. Ambos foram acionados apenas ao chamar fixture.detectChanges ().

Na primeira vez, resolvi usar a interpolação de strings com mais segurança no meu arquivo .html.

Exemplo inseguro :

<p>{{user.firstName}}</p>

Exemplo de seguro (r) (observe o ponto de interrogação):

<p>{{user?.firstName}}</p>

O mesmo pode se aplicar à vinculação de propriedade:

<p [innerText]="user?.firstName"></p>

Na segunda vez, eu estava usando um DatePipe em meu arquivo .html, mas a propriedade mock em que usei não era uma data.

arquivo .html:

<p>{{startDate | date: 'dd-MM-yyyy'}}</p>

Arquivo .ts (dados fictícios) ( errado ):

let startDate = 'blablah';

Arquivo .ts (dados fictícios) ( correto ):

let startDate = '2018-01-26';
Harryvederci
fonte
Qualquer comentário por que '?' a interpretação de strings é mais segura? Este trabalho no meu cenário.
Dylan Kapp,
2
@DylanKapp verifica se o objeto é nulo antes de tentar ler a propriedade do objeto. Consulte angular.io/guide/template-syntax#safe-navigation-operator para obter mais detalhes.
Christian Rondeau
18

Isso ocorre porque a estrutura jasmine não pode manipular o tipo ErrorEvent, portanto, não extrai a mensagem de erro e chama error.toString()esse objeto.

Acabei de registrar um problema no jasmine repo https://github.com/jasmine/jasmine/issues/1594

Contanto que não seja corrigido, você pode corrigir temporariamente o pacote jasmine instalado na pasta node_modules. No meu caso é

node_modules/jasmine/node_modules/lib/jasmine-core/jasmine.js

e, em seguida, altere a implementação do ExceptionFormatter deste

if (error.name && error.message) {
    message += error.name + ': ' + error.message;
} else {
    message += error.toString() + ' thrown';
}

para isso

if (error.name && error.message) {
    message += error.name + ': ' + error.message;
} else if (error.message) {
    message += error.message;
} else {
    message += error.toString() + ' thrown';
}

Isso ajuda a identificar o problema.

Ginie
fonte
3
Isso funcionou para mim em [email protected]. No entanto, eu tive que remendar node_modules/jasmine_core/lib/jasmine_core/jasmine.js
Roger Garza
Tão bom - levou um minuto para encontrar este post, mas salvou minha bunda. Obrigado. Mesma versão do núcleo de jasmim
Sr. Rogers
Depois de alterar isso, ele só foi impresso uncaughtpara mim, o que não foi útil. Então, adicionei o código para imprimirerror objeto e suas propriedades. if(error){ // message+=error; for(var propName in error) { propValue = error[propName] message+='error prop: '+propName+', value: '+propValue; } } . Este informações fornecidas extra que me ajudou na depuração - por exemploerror prop: filename, value: blob:http://localhost:9881/11777e3a-28d8-414e-9047-cee7d328e843
Manu Chadha
7

Para mim, estava relacionado a ter uma promessa resolvida na forma ngOnInitde um componente. Eu tive que usar async, fakeAsynce carrapatos, bem como apagando o serviço assíncrono comspyOn

beforeEach(async(
  //... initialise testbed and component
))
beforeEach(fakeAsync(
  // ... setup mocks then call:
  component.ngOnInit()
  tick()
  fixture.detectChanges()
))

Angular - como testar a unidade de componente com chamada de serviço assíncrona

roo2
fonte
4

TL; DR: pode estar relacionado ao roteamento de teste.

Eu também estou conseguindo [object ErrorEvent] thrown. Uma hora depois, rastreou até uma linha de código.

this.username = this.userService.getUser(this.route.snapshot.paramMap.get('id'))[0];

O problema está no ambiente de teste tentando avaliar this.route.snapshot.paramMap.get('id') .

Se eu substituí-lo por 0 , [object ErrorEvent] thrownvai embora.

Meu userService tem um usuário assim:

public users = [ ["admin", "First name", "Surname", etc... ] ].

assim 0 apenas pega esse usuário, no índice 0.

Caso contrário, quando normalmente estou executando meu aplicativo, this.route.snapshot.paramMap.get('id') é avaliado quando o usuário seleciona um usuário para editar na minha tabela de usuários.

Então, em meu HTML, *ngFor="let user of users; index as i"loops para exibir todos os usuários, routerLink="/edit/{{i}}"então você pode clicar nos botões de edição para cada usuário, que quando clicado vai para, por exemplo, http://localhost:4200/edit/0editar os detalhes do usuário administrador mencionado acima.

Leo
fonte
3

que tal a limpeza após cada caso de teste:

  afterEach(() => {
    TestBed.resetTestingModule();
  })
Sebastian Brestin
fonte
Eu li em algum lugar que o TestBed é reiniciado de qualquer maneira para cada teste.
dia
1
No meu caso, ajudou a limpar para os próximos testes.
Sebastian Brestin
1

Eu tive o mesmo problema. Uma forma de esse erro acontecer é quando você tenta acessar qualquer coisa nula ou indefinida no modelo. Certifique-se de ter verificação de segurança nessas variáveis.

Por exemplo, isso irá lançar [object: ErrorEvent] quando a configuração é indefinida no carregamento do componente.

template.html

<div *ngIf="config.options">
   .....
   ......
</div>

Faça isso ao invés

<div *ngIf="config?.options">
   .....
   ......
</div>
kashpatel
fonte
1

O que pode ajudar é, se você tiver a janela do Chrome aberta para o executor do teste Karma, abrir as ferramentas de desenvolvedor e verificar o console lá. Para mim, isso me ajudou a descobrir que o aplicativo não poderia usar o método Array.findIndex em uma matriz indefinida (porque a estrutura de dados foi organizada por uma string de data, como data [2018] [3] [28], e Acontece que eu estava apontando para a data errada), mas, ainda assim, em vez de apenas parar no erro, o teste continuou em execução.

OzzyTheGiant
fonte
Muitíssimo obrigado! Eu esperava que a informação estivesse presente no console, você salvou algumas horas da minha vida :)
Sébastien Tromp
0

Para mim, o problema era que eu tinha um teste em que estava usando acidentalmente a biblioteca auth0-lock .

Manolis
fonte
0

Parecia ser um problema assíncrono, porque depois de adicionar its suficientes em uma das especificações do meu componente, consegui obter uma mensagem de erro utilizável que apontava para um arquivo e uma linha dentro desse arquivo (estava relacionado ao paramMap.

Na especificação que testou o ParamMap, acabei de adicionar:

  describe('this test', () => {
    it('will succeed', () => {
      expect(true).toBeTruthy();
    });

    it('will succeed', () => {
      expect(true).toBeTruthy();
    });

    it('will succeed', () => {
      expect(true).toBeTruthy();
    });

    it('will succeed', () => {
      expect(true).toBeTruthy();
    });
  });
inorganik
fonte
0

Você pode ter uma corrida ou um teste assíncrono que não está configurado corretamente ou é usado incorretamente. Eu diria que o caso de depuração precisa ser corrigido e ignorar que a linha de comando passa. Continue atualizando o runner do teste karma (navegador) caso o erro [object ErrorEvent] thrownapareça de forma intermitente e certifique-se de ter implementado a condição assíncrona corretamente.

Espero que isso funcione.

Pradosh kumar Mohapatra
fonte
0

[object ErrorEvent] lançado

Este erro mostra que você tem algo indefinido. A maneira mais fácil de depurar com minha experiência é:

it('should create', () => {
    console.log(component);
    // You can check in the browser log which property is undefined
    });
Daniel Dimitrov
fonte
Na verdade, isso acabou se revelando o lembrete mais útil de todos: em meus testes, tenho um serviço de autenticação simulado, que perdeu um método. Aparentemente não relacionado, um dos testes em um componente falhou, mas não quando isolado. Rastreei o obscuro [object ErrorEvent] thrownaté aquele método remoto ausente apenas graças ao console.log :)
RedDree
0

No meu caso o problema era com o serviço, pois um dos objetos ficará indefinido durante a execução dos testes.

A amostra de código de serviço era algo como o acesso abaixo ao dom,

  const elem = this.document.querySelector(element) as HTMLElement;
  elem.scrollIntoView({param1: ''});

As especificações referentes a este serviço estavam falhando com o erro ' [objeto ErrorEvent] lançado '.

Eu zombei do meu objeto de serviço dentro de todas as especificações que se referiam a isso e o problema foi resolvido.

Serviço de simulação

class MockService {
serviceMethod(div) : void {
  testElement = document.querySelector('div') as HTMLElement;
  return testElement;
  } 
}

E use este objeto de serviço simulado em provedores conforme abaixo,

beforeEach(async(() => {

TestBed.configureTestingModule({
  declarations: [Component],
  providers: [
     { provide: Service, useClass: MockService },
    ],
})
  .compileComponents();
}));
Vishwa G
fonte
0

Eu estava usando um proxy em meu aplicativo definido em proxy.conf.json como:

'/api': { 'target': 'some path', 'changeOrigin': false }

Como o Karma não estava ciente desse proxy, ele continuou rastreando erros no console que o terminal da API não pôde ser encontrado. Então, depois de olhar a documentação do Karma, descobri que o que eu poderia fazer era adicionar a propriedade "proxies" em karma.conf.js com o mesmo objeto do proxy.conf.json:

proxies: { '/api': { 'target': 'some path', 'changeOrigin': false }}

O erro no console havia desaparecido e o [objeto errorEvent] não era mais lançado.

Arnold Layne
fonte
-1

No final, o que pode funcionar para mim:

    TestBed.resetTestingModule();
  })
Igor Korchagin
fonte