Как отладить ошибку "[object ErrorEvent] throwed" в моих тестах Karma/Jasmine?
У меня есть несколько провальных тестов, которые только выводят [object ErrorEvent] thrown
, Я не вижу в консоли ничего, что помогло бы мне точно определить нарушающий код. Есть ли что-то, что мне нужно сделать, чтобы отследить это?
[РЕДАКТИРОВАТЬ]: я бегу Карма v1.70, Жасмин v2.7.0
13 ответов
Чтобы исправить это, вы должны запустить тесты без исходных карт в качестве обходного пути:
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
так что теперь проблема ушла.
Если sourcemap=false не помогает, попробуйте 1) открыть браузер, на котором выполняются тесты 2) нажать кнопку отладки 3) открыть консоль
Там будет ошибка
Попробуйте, если вы получите более описательное сообщение об ошибке, запустив тест из терминала, например так:
ng test -sm=false
В своем тесте вы можете заменить
it('should...')
с
fit('should...')
Теперь будут выполняться только тесты, которым предшествует подгонка. Чтобы оставить браузер открытым после запуска теста, запустите тест следующим образом:
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, но свойство mock, на котором я его использовал, не было датой.
.html файл:
<p>{{startDate | date: 'dd-MM-yyyy'}}</p>
Файл.ts (mock-data) (неверный):
let startDate = 'blablah';
Файл.ts (mock-data) (правильный):
let startDate = '2018-01-26';
Это связано с тем, что среда jasmine не может обработать тип ErrorEvent, поэтому она не извлекает сообщение об ошибке и не вызывает error.toString()
на этом объекте вместо
Я только что подал вопрос в репозиторий Жасмин https://github.com/jasmine/jasmine/issues/1594
Пока это не исправлено, вы можете временно исправить установленный пакет жасмина в папке 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';
}
Это помогает определить проблему.
Для меня это было связано с разрешением обещания в ngOnInit
компонента. Я должен был использовать async
, fakeAsync
и отметьте, а также заглушить асинхронную службу с spyOn
beforeEach(async(
//... initialise testbed and component
))
beforeEach(fakeAsync(
// ... setup mocks then call:
component.ngOnInit()
tick()
fixture.detectChanges()
))
Angular - Как выполнить модульное тестирование компонента с помощью асинхронного вызова службы
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
редактировать вышеупомянутые данные администратора.
Как насчет очистки после каждого теста:
afterEach(() => {
TestBed.resetTestingModule();
})
Для меня это было вызвано тем, что я не определил обработчик ошибок для API, на который я подписан.
Мое исправление просто включало добавление блока кода для обработки (ошибка) ниже:
it('reports an error to subscribers of api calls if not authenticated', (done) => {
let obsDataFound = dataService.find(1);
obsDataFound.subscribe((app) => {
// not expecting this block to be called
done();
}, (err) => {
// This is the err block that I added that solved the problem
expect(true).toBeTruthy();
done();
});
let testRequest = httpMock.expectOne({method: 'GET'});
const mockErrorResponse = { status: 401, statusText: 'Unauthorized test status message' };
testRequest.flush(appTest, mockErrorResponse);
});
У меня такая же проблема. Одним из способов возникновения этой ошибки является попытка доступа к чему-либо пустому или неопределенному в шаблоне. Убедитесь, что у вас есть проверка безопасности этих переменных.
Например, это выдает [object: ErrorEvent], когда config не определен при загрузке компонента.
template.html
<div *ngIf="config.options">
.....
......
</div>
Сделай это вместо
<div *ngIf="config?.options">
.....
......
</div>
Что может помочь, если у вас открыто окно Chrome для вашего бегуна по тестированию Karma, чтобы открыть инструменты разработчика и проверить консоль там. Для меня это помогло мне узнать, что приложение не может использовать метод Array.findIndex для неопределенного массива (поскольку структура данных была организована в виде строки даты, такой как data[2018][3][28], и Я случайно указал на неправильную дату), но вместо того, чтобы просто остановиться на ошибке, тест продолжался.
[объект ErrorEvent] брошен
Эта ошибка показывает, что у вас есть что-то неопределенное. Самый простой способ отладить его из моего опыта:
it('should create', () => {
console.log(component);
// You can check in the browser log which property is undefined
});
У вас может быть гонка или асинхронный тест, который настроен неправильно или используется неправильно. Я хотел бы предположить, что отладочный случай должен быть исправлен и игнорировать прохождение командной строки. Просто продолжайте обновлять программу проверки кармы (браузер) на случай ошибки [object ErrorEvent] thrown
периодически появляется, затем убедитесь, что вы правильно выполнили условие асинхронности.
Надеюсь, это работает.
В моем случае проблема была с сервисом, так как один из объектов будет неопределенным во время выполнения тестов.
Пример сервисного кода был что-то вроде ниже доступа к 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();
}));
Это оказалось асинхронной проблемой, потому что после того, как я добавил достаточно it
s в одной из моих спецификаций компонентов, я смог получить полезное сообщение об ошибке, которое указывало на файл и строку в этом файле (это было связано с 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();
});
});
Для меня проблема заключалась в том, что у меня был тест, в котором я случайно использовал библиотеку auth0-lock.
Я использовал прокси в моем приложении, определенном в proxy.conf.json, например:
'/api': { 'target': 'some path', 'changeOrigin': false }
Поскольку Карма не знал об этом прокси, он продолжал выдавать ошибки в консоли, что конечная точка API не может быть найдена. Поэтому, просмотрев документацию по Карме, я обнаружил, что могу добавить свойство "прокси" в karma.conf.js с тем же объектом из proxy.conf.json:
proxies: { '/api': { 'target': 'some path', 'changeOrigin': false }}
Ошибка в консоли исчезла, и объект [errorEvent] больше не генерировался.
В конце концов, что может работать для меня:
TestBed.resetTestingModule();
})