可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have several failing tests that only output [object ErrorEvent] thrown
. I don't see anything in the console that helps me pinpoint the offending code. Is there something I need to do to track these down?
[EDIT]: I'm running Karma v1.70, Jasmine v2.7.0
回答1:
To fix that you have to run your tests without sourcemaps as a workaround:
CLI v6.0.8 and above
--source-map=false
CLI v6.0.x early versions
--sourceMap=false
CLI v1.x
--sourcemaps=false
Shortcut ng test -sm=false
might also work
There is an open issue on that https://github.com/angular/angular-cli/issues/7296
UPDATE:
I had that issue as well, so I just migrated to the latest cli and make sure that all packages are updated in package.json
also I fully reinstalled the node_modules
so now the issue has gone.
回答2:
If sourcemap=false doesn't help, try to
1) open your browser running the tests
2) click debug button
3) open the console
The error will be there
回答3:
Try if you get a more descriptive error message by running the test from the terminal, like this:
ng test -sm=false
In your test, you can replace
it('should...')
with
fit('should...')
Now only tests preceded by fit will run.
To leave the browser open after running the test, run the test like this:
ng test -sm=false --single-run false
Personally, I have encountered this error twice. Both were only triggered when calling fixture.detectChanges().
The first time, I solved it by using string interpolation more safely in my .html file.
Unsafe example:
<p>{{user.firstName}}</p>
Safe(r) example (note the question mark):
<p>{{user?.firstName}}</p>
The same may apply to property binding:
<p [innerText]="user?.firstName"></p>
The second time, I was using a DatePipe in my .html file, but the mock property that I used it on was not a date.
.html file:
<p>{{startDate | date: 'dd-MM-yyyy'}}</p>
.ts (mock-data) file (wrong):
let startDate = 'blablah';
.ts (mock-data) file (correct):
let startDate = '2018-01-26';
回答4:
This is because the jasmine framework can not handle the ErrorEvent type so it does not extract the error message and calls error.toString()
on that object instead.
I just filed an issue at jasmine repo
https://github.com/jasmine/jasmine/issues/1594
As long as it is not fixed, you can temporarily patch your installed jasmine package in the node_modules folder. In my case it is
node_modules/jasmine/node_modules/lib/jasmine-core/jasmine.js
and then change the implementation of the ExceptionFormatter from this
if (error.name && error.message) {
message += error.name + ': ' + error.message;
} else {
message += error.toString() + ' thrown';
}
to this
if (error.name && error.message) {
message += error.name + ': ' + error.message;
} else if (error.message) {
message += error.message;
} else {
message += error.toString() + ' thrown';
}
It helps to identify the issue.
回答5:
For me it was related to having a promise resolved in the ngOnInit
of a component. I had to use async
, fakeAsync
and tick as well as stubbing out the async service with spyOn
beforeEach(async(
//... initialise testbed and component
))
beforeEach(fakeAsync(
// ... setup mocks then call:
component.ngOnInit()
tick()
fixture.detectChanges()
))
Angular - How to unit test component with asynchronous service call
回答6:
TL;DR: It may be related to testing routing.
I'm getting [object ErrorEvent] thrown
too.
An hour later, traced it to one line of code.
this.username = this.userService.getUser(this.route.snapshot.paramMap.get('id'))[0];
The problem lies with the test environment attempting to evaluate this.route.snapshot.paramMap.get('id')
.
If I replace it with 0
, [object ErrorEvent] thrown
goes away.
My userService has a user like so:
public users = [ ["admin", "First name", "Surname", etc... ] ].
So 0
just gets this user, at index 0
.
Otherwise when normally running my app, this.route.snapshot.paramMap.get('id')
is evaluated when the user selects a user to edit from my table of users.
So in my HTML, *ngFor="let user of users; index as i"
loops to display all the users then routerLink="/edit/{{i}}"
so you can click on edit buttons for each user, which when clicked go to e.g. http://localhost:4200/edit/0
to edit the aforementioned admin user's details.
回答7:
I had the same problem. One way this error happens is when you try to access anything null or undefined in template. Make sure you have safety checking on those variable.
For example this will throw [object: ErrorEvent] when config is undefined on component load.
template.html
<div *ngIf="config.options">
.....
......
</div>
Do this instead
<div *ngIf="config?.options">
.....
......
</div>
回答8:
what about cleaning after each test case:
afterEach(() => {
TestBed.resetTestingModule();
})
回答9:
[object ErrorEvent] thrown
This error shows that you have something undefined. The easiest way to debug it from my experience is :
it('should create', () => {
console.log(component);
// You can check in the browser log which property is undefined
});
回答10:
For me the issue was that I had a test where I was accidentally using the auth0-lock library.
回答11:
It appeared to be an async problem, because after I added enough it
s in one of my component specs, I was able to get a usable error message which pointed to a file and line within that file (it was related to paramMap
.
In the spec that tested ParamMap, I just added:
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();
});
});
回答12:
You may have a race or an async test that isn't set up quite right or is used incorrectly. I would assume that the debug case needs to be fixed and ignore that the command line passes. Just keep refreshing the karma test runner (browser) in case the error [object ErrorEvent] thrown
appears intermittently, then make sure you have implemented the async condition correctly.
Hopefully this works.
回答13:
In my case the problem was with the service, as one of the object wil be undefined during tests running.
Service code sample was something like below access to dom,
const elem = this.document.querySelector(element) as HTMLElement;
elem.scrollIntoView({param1: ''});
The specs referring to this service were failing with the error '[object ErrorEvent] thrown'.
I mocked my service object inside all the specs which were referring to this and the issue got resolved.
Mock service
class MockService {
serviceMethod(div) : void {
testElement = document.querySelector('div') as HTMLElement;
return testElement;
}
}
And use this mock service object in providers as below,
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [Component],
providers: [
{ provide: Service, useClass: MockService },
],
})
.compileComponents();
}));
回答14:
What can help is, if you have the Chrome window open for your Karma test runner, to open the developer tools and check the console there. For me, this helped me to find out that the app could not use the Array.findIndex method on an undefined array (because the data structure was organized by a date string, such as data[2018][3][28], and I happened to be pointing to the wrong date), but yet instead of just stopping at the error, the test kept running.