Test angolari falliti con Impossibile eseguire 'send' su 'XMLHttpRequest'


145

Sto provando a testare il mio componente angolare 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>) {
  }
}

Tuttavia, un semplice test "dovrebbe creare" genera questo errore criptico ...

NetworkError: Impossibile eseguire 'send' su 'XMLHttpRequest': Impossibile caricare 'ng: ///DynamicTestModule/module.ngfactory.js'.

quindi ho trovato questa domanda, che suggerisce che il problema è che il componente ha @Input)_parametri che non sono impostati, tuttavia, se modifico il mio test in questo modo:

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

quindi ho ancora lo stesso problema, allo stesso modo, se rimuovo le @Input()annotazioni dal componente, ancora nessuna differenza. Come posso superare questi test?


1
Per creare un componente, è necessario fornire tutte le dipendenze. Puoi mostrare tutte le tue impostazioni di prova? Proverò a riprodurre il problema su plnkr
Aleksandr Petrovskij il

1
Ho avuto lo stesso problema e ho trovato gli stessi post che hai fatto tu. Sono stato in grado di trovare una soluzione. Ho finito per pubblicare post sull'altra domanda ma puoi dare un'occhiata qui: stackoverflow.com/a/45419372/6739517 Spero che sia d'aiuto!
Niles Tanner,

Risposte:


342

Questo è un problema del nuovo Angular Cli. Esegui il test con --sourcemaps=falsee otterrai i messaggi di errore corretti.

Vedi i dettagli qui: https://github.com/angular/angular-cli/issues/7296

MODIFICARE:

La scorciatoia per questo è:

ng test -sm=false

A partire dall'angolare 6 il comando è:

ng test --source-map=false


19
Sei un eroe assoluto. Stavo sbattendo la testa contro il muro frustrato dalla mancanza di informazioni dai messaggi di errore del test dell'unità angolare, fino a quando non ho trovato questo. Molto obbligato.
Alan Smith,

1
Questa risposta mi ha davvero salvato la giornata! Ero vicino a rinunciare allo sviluppo in generale dopo aver passato tutto il giorno e la notte a cercare di risolvere il problema solo per poter smettere di essere la persona che
falliva

Oggi mi sono imbattuto in questo messaggio di errore: HeadlessChrome 65.0.3325 (Mac OS X 10.13.4) ERRORE {"message": "Errore di script. \ Nat: 0: 0", "str": "Errore di script. \ Nat: 0 : 0 "} E la rimozione di --sourcemap = false mostra più informazioni.
penghui,

11
ng test --source-map = false ... funziona nella CLI angolare 6
danday74

@ danday74 FTW! Dopo aver scritto file di test complicati, rimanere bloccati su questo è brutale.
Brad Richardson,

21

Ho avuto lo stesso problema con Angualar Cli 6, ho usato questo tag per ottenere il messaggio di errore giusto:

ng test --source-map=false

Forse aiuterà qualcuno :).


8

Nel mio caso c'era un finto problema con i dati e, in caso Array, stavo tornando stringda quello.

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

Il messaggio di errore è davvero fonte di distrazione e non diceva l'errore reale. Running ha ng test --source=falseindicato l'errore e la riga corretti e mi ha aiutato a risolverlo rapidamente.

Molte volte accade quando si deridono dati incompleti o errati.


7

È possibile impostare la proprietà input () sul valore predefinito in component.ts

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

O

Modifica il tuo file component.spec.ts nel modo seguente,

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

4

Come suggerito sopra qui: https://stackoverflow.com/a/45570571/7085047 il mio problema era nel mio ngOnInit. Stavo chiamando un simulatore di controller REST generato da spavalderia. Stava tornando null e mi stavo iscrivendo a quel null, che non funziona ...

L'errore è tornato:

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

Ho risolto il problema usando ts-mockito: https://github.com/NagRock/ts-mockito

Ho aggiunto il codice per creare un'istanza finta come questa:

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 quindi ha aggiunto l'istanza all'array dei provider del test in questo modo:

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      ...
      providers: [
        ...
        { provide: VcmtsnodemockresourceApi, useValue: instanceMockVcmtsnodemockresourceApi },
        ...
      ]        
    }).compileComponents();
  }));

Se hai una nuova domanda, chiedila facendo clic sul pulsante Poni domanda . Includi un link a questa domanda se aiuta a fornire un contesto. - Dalla recensione
Anton Balaniuc,

sembrava che il mio sintomo fosse lo stesso dell'OP, quindi ho pensato che la gente potesse trovare utile la correzione che funzionava per me ...
Datum Geek,

3

Ciò può essere correlato al fatto che Chrome ha nascosto un errore di test effettivo. L'area di test confonderà alcuni falsi factory http che non può caricare e quindi questo è l'errore che segnalerà. Molto probabilmente l'errore sarà intorno all'area ngOnInit in cui un oggetto, ad esempio, si aspetta oggetti secondari e non sono definiti.

Per cercare di arrivare alla fine dell'errore, passa temporaneamente a PhantomJS, che sembra soffrire meno di questi errori di inizializzazione e questo, si spera, ti riporterà l'errore reale. Diverse occasioni ho scoperto di essere in cui un oggetto previsto per l'inizializzazione non era completo. IE:

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

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

La correzione dell'oggetto ha consentito il completamento di PhantomJS e anche Chrome per passare al test successivo.

A parte questo, non ho visto una soluzione per rimuovere il problema da Chrome. Come sempre, cerca di adottare un criterio "rimuovi il codice, fino a quando l'errore non scompare" per inseguire l'errore.

AGGIORNAMENTO: Nota che ora questa è una risposta piuttosto vecchia, non consiglierei più di usare PhantomJS (EOL). I rapporti sui test dei browser sono molto migliorati e se Chrome ti dà dolore, prova Firefox, che al giorno d'oggi esegue anche test molto bene.


2

Ho anche avuto questo errore, la cui verità è abbastanza non loquace.

Era correlato alle chiamate HTTP tramite i miei servizi

Uso myService.ts con 2 metodi

get();
getAll();

Sto deridendo questo servizio: mockMyService.ts

L'errore era qui perché il mio componente utilizzava il metodo getAll () che ho dimenticato di implementare in mockMyService, quindi ho appena aggiunto il metodo:

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);
}

Errore andato :)


2

Ho riscontrato lo stesso problema e ho scoperto che per risolverlo devi impostare i tuoi input per il componente nel metodo prima di ogni come mostrato di seguito:

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

Questo risolverà sicuramente il tuo problema.


1

Nel mio caso il colpevole è stato observable.timeout(x).retry(y)applicato da qualche parte sull'Osservabile restituito a livello di classe di servizio, quindi di nuovo nel componente che utilizzava quel servizio.

Tutto ha funzionato correttamente nel browser fino a angular-cli 1.4. Poi ha iniziato a fallire durante i test Karma (con un errore così sciocco). La soluzione era ovviamente quella di mettere in ordine questi operatori di timeout / tentativi.


1

Per me questo messaggio appare quando una simulazione è falsa nei miei test: di solito fornisci mockService nel bootstrap dei test. Se la tua derisione è incompleta o falsa, allora angolare restituisce questo stupido errore.

Maggiori informazioni sul mio caso qui


0

Quello che vorrei fare è:

Aggiungi console.log () s, riga dopo riga in ngOnint () e scopri fino a che punto arriva, quindi controlla la linea che non passerà attraverso.

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);
        })
    }

Questo non è riuscito sul mio test con lo stesso errore in questo post. Come mostrato sopra, avevo due console.logs. Il primo è passato attraverso, ma il secondo no. Quindi ho capito che il problema è on line const id = params.get ('id'); e l'ho risolto.

Spero che questo possa aiutare qualcuno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.