Как мне отладить ошибку «[object ErrorEvent] thrown» в моих тестах Karma / Jasmine?

108

У меня есть несколько неудачных тестов, которые только выводят [object ErrorEvent] thrown. Я не вижу в консоли ничего, что помогло бы мне определить проблемный код. Что мне нужно сделать, чтобы их отследить?

[РЕДАКТИРОВАТЬ]: Я использую Karma v1.70, Jasmine v2.7.0

Даррелл Брогдон
источник
Можете ли вы включить больше ошибок? Как несколько строк ошибки до и после?
Кевин
2
[object ErrorEvent] thrownбуквально все, что он говорит. Нет ничего ни до, ни после.
Даррелл Брогдон
1
К счастью, у меня возникла эта проблема буквально в то же время, когда вы публиковали этот вопрос, это оказался тег сценария "мошенник" (это также может быть ссылка css), который необходимо удалить (моя проблема была связана в CORS), а в случае css я просто добавил crossorigin = "anonymous". Проверьте свой код на наличие таких тегов script / css, в моем случае я обнаружил, что проблема вызвана совершенно другим компонентом!
TheDude
ты на угловой кли, не так ли? @DarrellBrogdon
kuncevic.dev
1
@TheDude Как вы сузили этот сценарий? Построчно? Или был какой-то процесс отладки, который помог вам сузить круг вопросов? У меня та же проблема, и единственная информация, которую я должен продолжить, - это сообщение: ошибка была выброшена в afterAll. Если я изолирую сам тест, изменив значение it()на fit(), даже если выполняется только этот единственный тест, ошибка все равно будет выдаваться. Какие-либо рекомендации по отладке для этого типа ошибки?
Knight

Ответы:

121

К вашему сведению: вы можете найти точную ошибку, просто открыв консоль DevTools, когда ваши тесты будут запущены.

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

CLI v6.0.8 и выше
--source-map=false

CLI v6.0.x ранние версии
--sourceMap=false

CLI v1.x
--sourcemaps=false

Ярлык ng test -sm=falseтакже может работать

По этому поводу есть открытая проблема https://github.com/angular/angular-cli/issues/7296

ОБНОВЛЕНИЕ : у меня тоже была эта проблема, поэтому я просто перешел на последнюю версию cli и убедился, что все пакеты обновлены, package.jsonтакже я полностью переустановил, node_modulesтак что теперь проблема исчезла.

kuncevic.dev
источник
3
это сработало для меня. Это помогло выявить, что проблема связана с неопределенной привязкой ввода.
JP Lew
10
Для angular-cli 6 --sourceMap=falseвроде работает.
skermajo
1
типичное
фасадное
1
Это решение больше не работает. Раньше было, но в 6.2.4 это не так
Майк
3
Я получаю Uncaught [object Object], брошенный в случайные компоненты, и в некоторых прогонах я ничего не получаю ... Я ненавижу Angular Testing.
Херардо Буэнростро Гонсалес
51

Если sourcemap = false не помогает, попробуйте 1) открыть браузер, в котором запущены тесты 2) нажмите кнопку отладки 3) откройте консоль

Ошибка будет там

введите описание изображения здесь

Виктор Бредихин
источник
8
Мне даже не нужно было нажимать кнопку отладки. Просто открытие консоли разработчика сработало для меня.
chris31389
Гениально! Я добавил опцию sourcemap везде, но в конце концов это дало мне необходимую информацию
SkarXa
1
У --sourcemaps=falseменя вещь не работала, но работала безупречно! Спасибо!
mrClean
Не очень помогает, если браузер закрывается сразу после теста. Думаю, я напишу кучу бесполезных тестов, чтобы держать окно открытым, как какой-то пещерный человек.
CoryCoolguy
24

Попробуйте, если вы получите более информативное сообщение об ошибке, запустив тест с терминала, например:

ng test -sm=false

В своем тесте вы можете заменить

it('should...')

с участием

fit('should...') 

Теперь будут запускаться только тесты, которым предшествует fit . Чтобы оставить браузер открытым после запуска теста, запустите тест следующим образом:

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

Лично я сталкивался с этой ошибкой дважды. Оба срабатывали только при вызове fixture.detectChanges ().

В первый раз я решил это, используя более безопасную интерполяцию строк в моем файле .html.

Небезопасный пример:

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

Пример безопасного (r) (обратите внимание на вопросительный знак):

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

То же самое может относиться к привязке свойств:

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

Во второй раз я использовал DatePipe в моем .html файле, но фиктивное свойство, в котором я его использовал, не было датой.

.html файл:

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

Файл .ts (mock-data) ( неверный ):

let startDate = 'blablah';

Файл .ts (mock-data) ( правильный ):

let startDate = '2018-01-26';
Harryvederci
источник
Любые комментарии, почему '?' интерпретация строк безопаснее? Это работа по моему сценарию.
Дилан Капп
2
@DylanKapp проверяет, является ли объект нулевым, прежде чем пытаться прочитать свойство объекта. См. Angular.io/guide/template-syntax#safe-navigation-operator для получения дополнительной информации.
Кристиан Рондо
18

Это связано с тем, что фреймворк jasmine не может обрабатывать тип ErrorEvent, поэтому он не извлекает сообщение об ошибке и error.toString()вместо этого вызывает этот объект.

Я только что зарегистрировал проблему в репозитории jasmine https://github.com/jasmine/jasmine/issues/1594

Пока это не исправлено, вы можете временно исправить установленный пакет jasmine в папке node_modules. В моем случае это

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

а затем измените реализацию ExceptionFormatter из этого

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

к этому

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

Это помогает определить проблему.

Джини
источник
3
Это сработало для меня в jasmine-core@2.99.1. Однако мне пришлось исправить это node_modules/jasmine_core/lib/jasmine_core/jasmine.js
Роджер Гарза
Так хорошо - я нашел этот пост за минуту, но он спас мою задницу. Спасибо. Та же самая версия с жасминовым ядром
мистер Роджерс
После изменения он распечатал только uncaughtдля меня, что не помогло. Поэтому я добавил код для печати errorобъекта и его свойств. if(error){ // message+=error; for(var propName in error) { propValue = error[propName] message+='error prop: '+propName+', value: '+propValue; } } . Это предоставило дополнительную информацию, которая помогла мне в отладке - напримерerror prop: filename, value: blob:http://localhost:9881/11777e3a-28d8-414e-9047-cee7d328e843
Ману Чадха
7

Для меня это было связано с выполнением обещания в ngOnInitкомпоненте. Я должен был использовать async, fakeAsyncи тик, а также гася службу асинхронной сspyOn

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

Angular - Как выполнить модульное тестирование компонента с помощью асинхронного вызова службы

roo2
источник
4

TL; DR: это может быть связано с тестированием маршрутизации.

Я [object ErrorEvent] thrownтоже получаю . Через час проследил до одной строчки кода.

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

Проблема заключается в том, что тестовая среда пытается выполнить оценку this.route.snapshot.paramMap.get('id').

Если я заменю его на 0, [object ErrorEvent] thrownисчезнет.

В моем userService есть такой пользователь:

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

Так 0что просто получает этого пользователя по индексу 0.

В противном случае при обычном запуске моего приложения this.route.snapshot.paramMap.get('id')выполняется оценка, когда пользователь выбирает пользователя для редактирования из моей таблицы пользователей.

Итак, в моем HTML *ngFor="let user of users; index as i"циклы для отображения всех пользователей, а затем routerLink="/edit/{{i}}"вы можете нажимать кнопки редактирования для каждого пользователя, которые при нажатии переходят, например, http://localhost:4200/edit/0к редактированию вышеупомянутых данных администратора.

Лео
источник
3

как насчет очистки после каждого теста:

  afterEach(() => {
    TestBed.resetTestingModule();
  })
Себастьян Брестин
источник
Я где-то читал, что TestBed все равно сбрасывается для каждого теста.
bgerth
1
В моем случае это помогло подготовиться к следующим испытаниям.
Себастьян Брестин
1

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

Например, это вызовет [объект: ErrorEvent], если конфигурация не определена при загрузке компонента.

template.html

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

Сделай это вместо

<div *ngIf="config?.options">
   .....
   ......
</div>
кашпатель
источник
1

Что может помочь, так это если у вас открыто окно Chrome для вашего тестового запуска Karma, чтобы открыть инструменты разработчика и проверить там консоль. Для меня это помогло мне узнать, что приложение не может использовать метод Array.findIndex в неопределенном массиве (поскольку структура данных была организована строкой даты, например data [2018] [3] [28] и Я указал не на ту дату), но все же вместо того, чтобы просто остановиться на ошибке, тест продолжал работать.

ОззиГигант
источник
Огромное спасибо! Я ожидал, что информация будет присутствовать в консоли, вы сэкономили пару часов моей жизни :)
Себастьен Тромп
0

Для меня проблема заключалась в том, что у меня был тест, в котором я случайно использовал библиотеку auth0-lock .

Манолис
источник
0

Это оказалось асинхронной проблемой, потому что после того, как я добавил достаточно its в одну из моих спецификаций компонента, я смог получить полезное сообщение об ошибке, которое указывало на файл и строку в этом файле (это было связано с paramMap.

В спецификации, которая тестировала ParamMap, я только что добавил:

  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();
    });
  });
неорганик
источник
0

У вас может быть гонка или асинхронный тест, который настроен неправильно или используется неправильно. Я бы предположил, что случай отладки должен быть исправлен, и проигнорировал бы передачу командной строки. Просто продолжайте обновлять средство запуска теста кармы (браузер) на случай, если ошибка [object ErrorEvent] thrownпоявляется периодически, затем убедитесь, что вы правильно выполнили условие асинхронности.

Надеюсь, это сработает.

Прадош кумар Мохапатра
источник
0

[объект ErrorEvent] брошен

Эта ошибка показывает, что у вас что-то не определено. По моему опыту, самый простой способ отладить это:

it('should create', () => {
    console.log(component);
    // You can check in the browser log which property is undefined
    });
Даниил Димитров
источник
На самом деле это оказалось самым полезным напоминанием из всех: в моих тестах у меня есть фиктивная служба аутентификации, в которой пропущен метод. На первый взгляд несвязанный, один из тестов в компоненте завершился неудачно, но не в изолированном состоянии. Я отследил неясность [object ErrorEvent] thrownдо этого удаленного метода пропажи только благодаря console.log :)
RedDree
0

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

Пример кода службы выглядел примерно так, как показано ниже: доступ к dom,

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

Спецификации, относящиеся к этой службе, не работали с ошибкой « [объект ErrorEvent] брошен ».

Я издевался над своим сервисным объектом во всех спецификациях, которые относились к этому, и проблема была решена.

Мок-сервис

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

И используйте этот фиктивный объект службы в поставщиках, как показано ниже,

beforeEach(async(() => {

TestBed.configureTestingModule({
  declarations: [Component],
  providers: [
     { provide: Service, useClass: MockService },
    ],
})
  .compileComponents();
}));
Вишва Г
источник
0

Я использовал прокси в своем приложении, определенном в proxy.conf.json, например:

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

Поскольку Karma не знала об этом прокси, она продолжала выдавать ошибки в консоли, что конечная точка API не может быть найдена. Поэтому, просмотрев документацию Karma, я обнаружил, что могу добавить свойство proxies в karma.conf.js с тем же объектом из proxy.conf.json:

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

Ошибка в консоли исчезла, и [объект errorEvent] больше не генерировался.

Арнольд Лэйн
источник
-1

В конце концов, что может у меня сработало:

    TestBed.resetTestingModule();
  })
Игорь Корчагин
источник