Reputation: 923
I have angular 2 webpack application, all webpack,karma configuration created as per angular.io webpack guide. I am not using aot. I am writing jasmine unit test spec to test my components. First I tried without async block, in that case , unit test just get execute only till fixture.detectChanges() call, code after that doesn't get executed. Seems like fixture.detectChanges call getting blocked infinitely.
I tried by including code in async block. Then I get following error. Error:Failed to execute 'send' on 'XMLHttpRequest' : Failed to load 'ng:///DynamicTestModule/module.ngfactory.js'
Code without async
beforeeach(()=> {
TestBed.configureTestingModule({
imports:[],
declaration :[Mycomp],
providers:[{ provide:MyService, useclass:MyMockService}]
});
fixture=TestBed.createComponent(Mycomp);
console.log(' before detect changes'):
fixture.detectChanges():
console.log('after detect changes');// this is not getting
logged .. karma shows 0 of 1 executed successfully
});
With async
beforeeach(async(()=> {
TestBed.configureTestingModule({
imports:[],
declaration :[Mycomp],
providers:[{ provide:MyService, useclass:MyMockService}]
});
fixture=TestBed.createComponent(Mycomp);
fixture.detectChanges():
}));
getting error Failed to load dynamictestmodule/module.ngfactory.js
Upvotes: 64
Views: 37457
Reputation: 14863
I had the same error when I accessed a variable of an undefined object.
Example:
Component:
soemthing = {}
Template:
<demo-something [someinput]="something.anotherthing.data"> ...
So something
was defined, anotherthing
was undefined and data
could therefor not be accessed.
Very annoying error and as far as I could tell not in the list yet :)
Upvotes: 0
Reputation: 21641
To find out what's really causing the error, disable source maps:
For angular-cli >= v6.x:
ng test --source-map=false
For angular-cli v1.x:
ng test -sm=false
You will then see a better error, e.g. "Cannot read property 'x' of undefined" in the actual source file that's causing the error. For some reason, there's a bug with sourcemaps right now in testing, and you just get this cryptic error.
Upvotes: 77
Reputation: 2178
I just had this issue as well. It turned out to be a simple null reference error in my component in one of my *ngIf checks.
I would suggest running ng serve and checking the component is working in the browser without any errors, or simply run ng test --source-map=false to get a more useful error message.
Upvotes: 0
Reputation: 2052
Adding on to Dan Field's answer
This is a problem with the Angular Cli
version 1.2.2 or newer. Run your test with --sourcemaps=false
and you will get the right error messages.
ng test --sourcemaps=false
shorthand for this is:
ng test -sm=false
See details here: https://github.com/angular/angular-cli/issues/7296
Upvotes: 6
Reputation: 4360
In my case, my mock service was missing some public variables accessed by the component in the ngOnInit method.
Upvotes: 1
Reputation: 1073
I ran into this issue myself yesterday. The problem was that I had an Input() property on my component class that I wasn't setting in the test. So for example, in my-component.ts:
@Component({
selector: 'my-component'
})
export class MyComponent {
@Input() title: string;
}
and my-component.spec.ts:
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
component.title = 'Hello there!' // <-- this is required!
fixture.detectChanges();
});
Or you could provide a default value in the component somewhere. Either way, the test will crash if any inputs are not set and you'll get that unintuitive error.
Note: Running ng test -sm=false
will give the actual error message causing the problem. Credit: https://stackoverflow.com/a/45802115/61311
Upvotes: 104
Reputation: 8655
running tests with --sourcemaps=false
will not fail Karma silently but give you some detail about the error instead.
Upvotes: 18
Reputation: 8655
I was bitten by the same error next day - this time the problem was buried in the HTML file. Using a simple array length test for *ngIf
<ng-container *ngIf="myArray.length > 0">
had to be refactored into
<ng-container *ngIf="myArrayNotEmpty">
with a getter as in:
get myArrayNotEmpty(){
return this.myArray && this.myArray.length > 0;
}
I am a bit irritated though that such a variety of causes is covered by one very misleading and unhelpful message.
Upvotes: 2
Reputation: 8655
This is the most deceiving error message that I've ever encountered in Angular.
In my case it had nothing to do with sending, nothing to do with XmlHttpRequest - at least not on the level you'd guess when trying to follow the message.
It was too about mocking a class, namely ngrx/store. I introduced two Observable methods in a container that had not been included in my mock-up class before and I forgot to do so when I started using those. Once added to the mock-up, the error went away.
...leaving Karma happy to be able to execute 'send' from the XmlHttpRequest whatever it means.
Upvotes: 3
Reputation: 4021
I also had this issue and it was due to malformed mocked data. In my component I had a service which made a http call.
something like: (service code)
getData() {
return this.http.get(obj);
}
In the component I called this function and subscribed to it: (component code)
this.service.getData().subscribe((data) => {
this.componentData = data.things; //**<=== part that broke everything**
}, (error) => {
console.log(error);
});
Solution:
When I mocked out the service function I failed to return data that had the attribute things
. This is what caused the XMLHttpRequest failure, I guess to angular it looked like the error happened as if it was the HTTP request. Making sure that I returned the correct attributes on any mocked HTTP requests fixed the issues.
Hope this clears things up. Below is the code for the implementation of the mock.
(component.specs)
function fakeSubscribe(returnValue,errorValue) {
return {
subscribe:function(callback,error){
callback(returnValue);
error(errorValue);
}
}
}
class MockService {
getData() {
var fakeData = {
things:[]
}
return fakeSubscribe(fakeData,0);
}
}
Upvotes: 5