Angular тесты не работают с Failed to execute 'send' on 'XMLHttpRequest'

149

Я пытаюсь протестировать свой угловой компонент 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>) {
  }
}

Однако простой тест «должен создать» вызывает эту загадочную ошибку ...

NetworkError: не удалось выполнить 'send' на 'XMLHttpRequest': не удалось загрузить 'ng: ///DynamicTestModule/module.ngfactory.js'.

поэтому я нашел этот вопрос, который предполагает, что проблема в том, что у компонента есть @Input)_параметры, которые не установлены, однако, если я изменю свой тест следующим образом:

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

то у меня все еще возникает та же проблема, аналогично, если я удалю @Input()аннотации из компонента, все равно никакой разницы. Как я могу пройти эти тесты?

Джордж Эдвардс
источник
1
Чтобы создать компонент, вам необходимо указать все зависимости. Вы можете показать всю свою тестовую установку? Постараюсь
Александр Петровский
1
У меня была такая же проблема, и я нашел те же сообщения, что и вы. Я смог найти решение. Я закончил публикацию по другому вопросу, но вы можете посмотреть здесь: stackoverflow.com/a/45419372/6739517 Надеюсь, это поможет!
Niles Tanner

Ответы:

346

Это проблема нового Angular Cli. Запустите тест с помощью, --sourcemaps=falseи вы получите правильные сообщения об ошибках.

Подробности здесь: https://github.com/angular/angular-cli/issues/7296

РЕДАКТИРОВАТЬ:

Сокращение для этого:

ng test -sm=false

Начиная с angular 6 команда:

ng test --source-map=false

Penghui
источник
20
Вы абсолютный герой. Я бился головой о стену, разочарованный отсутствием информации из сообщений об ошибках модульного теста Angular, пока не нашел это. Весьма признателен.
Алан Смит
1
Этот ответ действительно спас мне день! Я был близок к тому, чтобы вообще отказаться от разработки, потратив целый день и ночь на то, чтобы исправить это, просто чтобы перестать быть человеком, который терпит неудачу при сборке
user1806692
Сегодня я столкнулся с этим сообщением об ошибке: HeadlessChrome 65.0.3325 (Mac OS X 10.13.4) ERROR {"message": "Ошибка сценария. \ Nat: 0: 0", "str": "Ошибка сценария. \ Nat: 0 : 0 "} И удаление --sourcemap = false показывает больше информации.
Penghui
11
ng test --source-map = false ... работает в Angular CLI 6
danday74 09
@ danday74 FTW! После написания сложных тестовых файлов зацикливаться на этом жестоко.
Брэд Ричардсон
21

У меня была такая же проблема с использованием angualar cli 6, я использовал этот тег, чтобы получить правильное сообщение об ошибке:

ng test --source-map=false

Может кому поможет :).

Jmuhire
источник
8

В моем случае возникла проблема с фиктивными данными, и в случае возникновения Arrayя возвращался stringиз макета.

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

Сообщение об ошибке действительно отвлекает и не говорит об ошибке. Бег ng test --source=falseуказал на правильную ошибку и строку и помог мне быстро ее исправить.

Часто это случается, когда вы имитируете неполные или неверные данные.

Анируддха Дас
источник
8

Вы можете установить для свойства input () значение по умолчанию в component.ts

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

ИЛИ

Измените файл component.spec.ts следующим образом:

beforeEach(() => {  
   fixture = TestBed.createComponent(MyComponent);  
   component = fixture.componentInstance;  
   component.tableColumns = [];  
   component.pageObj = '';  
   fixture.detectChanges();  
});
Мангеш Даундкар
источник
4

Как было предложено выше здесь: https://stackoverflow.com/a/45570571/7085047, моя проблема была в моем ngOnInit. Я вызывал прокси-сервер REST, созданный с помощью псевдонима. Он возвращал null, и я подписывался на этот null, который не работает ...

Ошибка вернулась:

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

Я исправил проблему с помощью ts-mockito: https://github.com/NagRock/ts-mockito

Я добавил код для создания такого имитационного экземпляра:

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

А затем добавил экземпляр в массив поставщиков тестов следующим образом:

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      ...
      providers: [
        ...
        { provide: VcmtsnodemockresourceApi, useValue: instanceMockVcmtsnodemockresourceApi },
        ...
      ]        
    }).compileComponents();
  }));
Datum Geek
источник
Если у вас есть новый вопрос, задайте его, нажав кнопку « Задать вопрос» . Включите ссылку на этот вопрос, если она помогает понять контекст. - Из
отзыва
казалось, что мой симптом был таким же, как и у OP, поэтому я подумал, что людям может быть полезно исправление, которое сработало для меня ...
Datum Geek
3

Я столкнулся с той же проблемой, и я обнаружил, что для ее исправления вам необходимо установить свои входы для компонента в методе beforeEach, как показано ниже:

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

Это определенно решит вашу проблему.

Джаянт Патил
источник
3

Это может быть связано с тем, что Chrome скрывает фактическую ошибку теста. Тестовая область будет сбивать с толку какую-то фиктивную фабрику http, которую она не может загрузить, и поэтому это ошибка, о которой он сообщит. Скорее всего, ошибка будет связана с областью ngOnInit, где объект, скажем, ожидает подобъекты, а они не определены.

Чтобы попытаться разобраться в проблеме, временно переключитесь на PhantomJS, который, кажется, меньше страдает от этих ошибок инициализации, и, надеюсь, он сообщит вам о фактической ошибке. Несколько раз я обнаруживал, что объект, ожидаемый при инициализации, не был завершен. IE:

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

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

Исправление объекта позволило завершить PhantomJS, а также Chrome перейти к следующему тесту.

Кроме этого, я не видел решения для устранения проблемы в Chrome. Как всегда, попробуйте применить политику «удалить код, пока ошибка не исчезнет», чтобы устранить ошибку.

ОБНОВЛЕНИЕ: обратите внимание, что это довольно старый ответ, я бы больше не рекомендовал использовать PhantomJS (EOL). Отчеты о тестировании браузера стали намного лучше, и если Chrome вас огорчает, попробуйте Firefox, который в настоящее время также отлично выполняет тесты.

PeterS
источник
2

У меня тоже была эта ошибка, которая, по правде говоря, довольно не разговорчива.

Это было связано с HTTP-вызовами через мои службы

Я использую myService.ts двумя способами

get();
getAll();

Я издеваюсь над этой службой: mockMyService.ts

Ошибка произошла из-за того, что мой компонент использовал метод getAll (), который я забыл реализовать в mockMyService, поэтому я просто добавил метод:

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

Ошибка исчезла :)

Deunz
источник
1

В моем случае виновник был observable.timeout(x).retry(y)применен где-то к возвращаемому Observable на уровне класса обслуживания, а затем снова к компоненту, который использовал эту службу.

В браузере все работало корректно вплоть до angular-cli 1.4. Потом начал глючить во время тестов Кармы (с такой глупой ошибкой). Решением было, конечно, убрать эти операторы тайм-аута / повтора.

Марчин Р
источник
1

Для меня это сообщение появляется, когда в моих тестах макет ложный: обычно вы предоставляете mockService в начальной загрузке тестов. Если ваш макет неполный или ложный, то angular вернет эту глупую ошибку.

Больше информации по моему делу здесь

Реболон
источник
0

Я бы сделал следующее:

Добавьте console.log (), строку за строкой в ​​ngOnint () и узнайте, как далеко он зашел, а затем проверьте строку, через которую он не пройдет.

Пример:

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

Это не удалось в моем тесте с той же ошибкой в ​​этом посте. Как показано выше, у меня было два console.logs. Первый прошел, а второй нет. Итак, я понял, что проблема в строке const id = params.get ('id'); и я исправил это.

Надеюсь, это кому-то поможет.

Йосф
источник