Testes angulares falhando com Falha ao executar 'send' em 'XMLHttpRequest'

145

Estou tentando testar meu componente angular 4.1.0 -

export class CellComponent implements OnInit {
  lines: Observable<Array<ILine>>;
  @Input() dep: string;
  @Input() embedded: boolean;
  @Input() dashboard: boolean;
  constructor(
    public dataService: CellService,
    private route: ActivatedRoute,
    private router: Router, private store: Store<AppStore>) {
  }
}

No entanto, um teste simples "deve criar" gera esse erro enigmático ...

NetworkError: falha ao executar 'send' em 'XMLHttpRequest': falha ao carregar 'ng: ///DynamicTestModule/module.ngfactory.js'.

então encontrei esta pergunta, que sugere que o problema é que o componente possui @Input)_parâmetros que não estão definidos, no entanto, se eu modificar meu teste da seguinte forma:

  it('should create', inject([CellComponent], (cmp: CellComponent) => {
    cmp.dep = '';
    cmp.embedded = false;
    cmp.dashboard = false;
    expect(cmp).toBeTruthy();
  }));

ainda continuo com o mesmo problema; da mesma forma, se remover as @Input()anotações do componente, ainda não há diferença. Como posso passar esses testes?

George Edwards
fonte
1
Para criar um componente, você precisa fornecer todas as dependências. Você pode mostrar toda a sua configuração de teste? Vou tentar reproduzir o problema em plnkr
Aleksandr Petrovskij
1
Eu tive esse mesmo problema e encontrei as mesmas postagens que você encontrou. Consegui encontrar uma solução. Acabei postando sobre a outra pergunta, mas você pode dar uma olhada aqui: stackoverflow.com/a/45419372/6739517 Espero que ajude!
Niles Tanner

Respostas:

342

Este é um problema do novo Angular Cli. Execute seu teste --sourcemaps=falsee você receberá as mensagens de erro corretas.

Veja detalhes aqui: https://github.com/angular/angular-cli/issues/7296

EDITAR:

A abreviação para isso é:

ng test -sm=false

A partir do angular 6, o comando é:

ng test --source-map=false

penghui
fonte
19
Você herói absoluto. Eu estava batendo minha cabeça contra a parede, frustrado com a falta de informações das mensagens de erro do teste de unidade angular, até encontrar isso. Muito grato.
Alan Smith
1
Esta resposta realmente salvou o meu dia! Eu estava perto de desistir em desenvolvimento em geral, depois de passar o dia todo e noite tentando corrigir isso apenas para que eu pudesse deixar de ser a pessoa não a construção
user1806692
Hoje me deparei com esta mensagem de erro: HeadlessChrome 65.0.3325 (Mac OS X 10.13.4) ERRO {"message": "Erro de script. \ Nat: 0: 0", "str": "Erro de script. \ Nat: 0 : 0 "} E a remoção de --sourcemap = false mostra mais informações.
Penghui
11
ng test --source-map = false ... funciona no Angular CLI 6
danday74
@ danday74 FTW! Depois de escrever arquivos de teste complicados, ficar preso é brutal.
21418 Brad
21

Eu tive o mesmo problema usando o angualar cli 6, usei essa tag para obter a mensagem de erro correta:

ng test --source-map=false

Talvez ajude alguém :).

jmuhire
fonte
8

Para o meu caso, havia um problema de dados simulados e, no caso de Array, eu estava retornando stringda simulação.

someApi = fixture.debugElement.injector.get(SomeApi);
spyOn(someApi, 'someMethod')
  .and.returnValue(Observable.of('this is not a string but array'));

A mensagem de erro é realmente perturbadora e não estava informando o erro real. A execução ng test --source=falseapontou o erro e a linha corretos e me ajudou a corrigi-lo rapidamente.

Muitas vezes isso acontece quando você zomba de dados incompletos ou incorretos.

Aniruddha Das
fonte
7

Você pode definir a propriedade input () como o valor padrão em component.ts

@Input() tableColumns: Array<any> = [];  
@Input() pageObj: any = '';

OU

Modifique seu arquivo component.spec.ts da seguinte maneira,

beforeEach(() => {  
   fixture = TestBed.createComponent(MyComponent);  
   component = fixture.componentInstance;  
   component.tableColumns = [];  
   component.pageObj = '';  
   fixture.detectChanges();  
});
Mangesh Daundkar
fonte
4

Como sugerido acima aqui: https://stackoverflow.com/a/45570571/7085047 meu problema estava no meu ngOnInit. Eu estava chamando um proxy de controlador REST simulado gerado por arrogância. Ele estava retornando nulo, e eu estava assinando esse nulo, o que não funciona ...

O erro voltou:

Failed to load ng:///DynamicTestModule/MockNodeDashboardComponent_Host.ngfactory.js: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

Corrigi o problema usando o ts-mockito: https://github.com/NagRock/ts-mockito

Eu adicionei código para criar uma instância simulada como esta:

import { mock, instance, when } from 'ts-mockito';
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';
import { MockScenario } from './vcmts-api-client/model/MockScenario';

const MockVcmtsnodemockresourceApi: VcmtsnodemockresourceApi = mock(VcmtsnodemockresourceApi);
const obs = Observable.create((observer: Observer<MockScenario[]>) => {
  observer.next(new Array<MockScenario>());
  observer.complete();
});
when(MockVcmtsnodemockresourceApi.getMockScenariosUsingGET()).thenReturn(obs);
const instanceMockVcmtsnodemockresourceApi: VcmtsnodemockresourceApi = instance(MockVcmtsnodemockresourceApi);

E, em seguida, adicionou a instância à matriz de provedores do teste como esta:

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      ...
      providers: [
        ...
        { provide: VcmtsnodemockresourceApi, useValue: instanceMockVcmtsnodemockresourceApi },
        ...
      ]        
    }).compileComponents();
  }));
Datum Geek
fonte
Se você tiver uma nova pergunta, faça-o clicando no botão Fazer pergunta . Inclua um link para esta pergunta se ela ajudar a fornecer contexto. - Do comentário
Anton Balaniuc 1/11
Parecia que o meu sintoma era o mesmo que o OP, então eu pensei que as pessoas podem ser úteis a correção que funcionou para mim ...
Datum Geek
3

Isso pode estar relacionado ao fato de o Chrome ocultar um erro de teste real. A área de teste estará confundindo alguma fábrica http falsa que não pode ser carregada e, portanto, esse é o erro que será relatado. Provavelmente, o erro ocorrerá na área ngOnInit onde um objeto está, digamos, esperando subobjetos e eles não estão definidos.

Para tentar chegar ao fundo do erro, mude para o PhantomJS temporariamente, o que parece sofrer menos com esses erros de inicialização e, com sorte, isso reportará o erro real a você. Várias ocasiões em que achei que um objeto esperado na inicialização não estava completo. IE:

    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;

    component.object = {}
// should be:
    component.object = {"innerObjectThatIsNeeded" : []}

A correção do objeto permitiu ao PhantomJS concluir e também o Chrome passou para o próximo teste.

Fora isso, não vi uma solução para remover o problema do Chrome. Como sempre, tente adotar uma política "remova o código até que ocorra o erro" para perseguir o erro.

ATUALIZAÇÃO: Observe que agora é uma resposta bastante antiga, eu não recomendaria mais o PhantomJS (EOL). Os relatórios de teste do navegador ficaram muito melhores e, se o Chrome estiver sofrendo, tente o Firefox, que também executa testes muito bons atualmente.

PeterS
fonte
2

Eu também tive esse erro, cuja verdade seja dita não é faladora.

Estava relacionado às chamadas HTTP através dos meus serviços

Eu uso myService.ts com 2 métodos

get();
getAll();

Estou zombando deste serviço: mockMyService.ts

O erro estava aqui porque meu componente estava usando o método getAll () que eu esqueci de implementar no mockMyService, então acabei de adicionar o método:

private mockObjects = [
{
  'id': '1',
  'champ1': 'TECH',
  'champ2': 2,
  'champ3': 'Data bidon'
},
{
  'id': '2',
  'champ1': 'TECH',
  'champ2': 2,
  'champ3': 'Data au pif'
},
{
  'id': '3',
  'champ1': 'FUNC',
  'champ2': 3,
  'champ3': 'Data quelconque'
},
 ];

getAll(): Observable<any> {
  return Observable.of(this.mockObjects);
}

O erro se foi :)

Deunz
fonte
2

Eu enfrentei o mesmo problema e descobri que, para corrigi-lo, você deve definir suas entradas para o componente no método beforeEach, como mostrado abaixo:

beforeEach(() => {
    fixture = TestBed.createComponent(CellComponent );
    cmp = fixture.debugElement.componentInstance;
    cmp.dep = '';
    cmp.embedded = false;
    cmp.dashboard = false;
    fixture.detectChanges();
});

Isso definitivamente resolverá seu problema.

Jayant Patil
fonte
1

No meu caso, o culpado foi observable.timeout(x).retry(y)aplicado em algum lugar no Observable retornado no nível da classe de serviço e, novamente, no componente que estava usando esse serviço.

Tudo funcionou corretamente no navegador até o angular-cli 1.4. Então começou a falhar durante os testes de Karma (com um erro tão bobo). Obviamente, a solução era arrumar esses operadores de tempo limite / nova tentativa.

Marcin R
fonte
1

Para mim, essa mensagem aparece quando um mock é falso nos meus testes: geralmente você fornece mockService no bootstrap de seus testes. Se o seu mock for incompleto ou falso, o angular retornará esse erro estúpido.

Mais informações sobre o meu caso aqui

Rebolon
fonte
0

O que eu estaria fazendo é:

Adicione console.log () s, linha após linha no ngOnint () e descubra até onde vai, depois inspecione a linha pela qual não passará.

Ex:

ngOnInit() {
    this.route.paramMap
        .switchMap(params => {
            this.busy = true;
            this.updateErrors(null);

            console.log(params);

            **const id = params.get('id');**
            console.log(id);

            if (id === 'new') {
                this.editMode = true;
                return Observable.of(GroupComponent.newGroup());
            }
            return this.apiService.getGroup(id);
        })
    }

Isso estava falhando no meu teste com o mesmo erro neste post. Como mostrado acima, eu tinha dois console.logs. O primeiro passou completamente, mas o segundo não. Então percebi que o problema está na linha const id = params.get ('id'); e eu consertei.

Espero que isso ajude alguém.

Josf
fonte