2017-05-30 108 views
44

我有angular 2 webpack应用程序,所有webpack,根据angular.io webpack指南创建的karma配置。 我不使用aot。 我正在写茉莉花单元测试规范来测试我的组件。 首先,我尝试没有异步块,在这种情况下,单元测试只能得到执行,直到fixture.detectChanges()调用,之后的代码不会被执行。看起来像fixture.detectChanges调用无限地被阻止。Angular 2单元测试 - 获取错误无法加载'ng:///DynamicTestModule/module.ngfactory.js'

我尝试通过在异步块中包含代码。 然后我得到以下错误。 错误:无法执行 '发送' 上 '的XMLHttpRequest':无法加载 'NG:/// DynamicTestModule /module.ngfactory.js'


代码,而异步

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 

}); 

随着异步

beforeeach(async(()=> { 
TestBed.configureTestingModule({ 
    imports:[], 
    declaration :[Mycomp], 
    providers:[{ provide:MyService,  useclass:MyMockService}] 
    }); 
    fixture=TestBed.createComponent(Mycomp); 
    fixture.detectChanges(): 
    })); 

得到错误无法加载dynamictestmodule/module.ngfactory.js

回答

59

昨天我自己遇到了这个问题。问题是我的组件类有一个Input()属性,我没有在测试中设置。因此,例如,在我-component.ts:

@Component({ 
    selector: 'my-component' 
}) 
export class MyComponent { 
    @Input() title: string; 
} 

和我-component.spec.ts:

beforeEach(() => { 
    fixture = TestBed.createComponent(MyComponent); 
    component = fixture.componentInstance; 
    component.title = 'Hello there!' // <-- this is required! 
    fixture.detectChanges(); 
}); 

或者你可以提供某个部件中的默认值。无论哪种方式,如果没有设置任何输入,测试将会崩溃,您将得到那个不直观的错误。

注意:运行ng test -sm=false会给出导致问题的实际错误消息。积分:https://stackoverflow.com/a/45802115/61311

+0

这是真的,但我也得到了同样的错误,有时,当我有没有正确嘲笑或服务如果我的组件试图访问其中一个服务返回的空值。仍然是一个有效的答案,但要注意,这可能并不总能解决问题。 – blo0p3r

+13

刚刚发现,通过将'sourcemap'选项设置为false可以得到更好的错误信息:'ng test --sourcemap = false' – blo0p3r

+0

@ blo0p3r这是一个很好的结果!将sourcemap设置为false会将无用的XMLHttpRequest错误转换为实际的根错误。 – newclearwinter

5

我也有这个问题,这是由于歪曲的数据。 在我的组件中,我有一个服务做了一个http调用。

是这样的:(服务代码

getData() { 
    return this.http.get(obj); 
} 

在我称这个功能组件,并订阅了它:(组件代码

this.service.getData().subscribe((data) => { 
    this.componentData = data.things; //**<=== part that broke everything** 
}, (error) => { 
    console.log(error); 
}); 

解决方案:

当我嘲笑的时候e服务功能我无法返回具有属性things的数据。这是导致XMLHttpRequest失败的原因,我猜测它看起来像发生错误就好像它是HTTP请求一样。确保我在任何模拟的HTTP请求上返回了正确的属性,修复了这些问题。

希望这可以解决问题。以下是模拟实现的代码。

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

正试图弄清楚这一点,以及类似的概念。当组件期望Observable时,我的模拟服务返回的类型不是Observable。 –

3

这是我在角一生中遇到的最迷惑人的错误消息。

对我来说,它有无关发送,无关的XmlHttpRequest - 至少不是在试图跟随消息时,你猜的水平。

这是嘲笑一类,即ngrx /店。我在一个容器中引入了两个Observable方法,这些方法之前没有包含在我的模拟类中,而当我开始使用这些方法时,我忘了这么做。一旦添加到模型中,错误就消失了。

...离开噶高兴能够从XmlHttpRequest执行“发送”,无论它是什么意思。

+0

你能举一个你如何解决它的例子吗? – KevinOrfas

+0

@KevinOrfas,我有同样的问题和类似的解决方案,我的问题。就我而言,嵌套在组件内部的组件是测试了一个HTTP调用。我需要嘲笑HTTP服务来克服它们奇怪的错误。 – tylerjgarland

1

第二天我被同样的错误咬了 - 这次问题被掩埋在HTML文件中。使用一个简单的数组长度测试*ngIf

<ng-container *ngIf="myArray.length > 0"> 

不得不被重构到

<ng-container *ngIf="myArrayNotEmpty"> 

吸气剂,如:

get myArrayNotEmpty(){ 
    return this.myArray && this.myArray.length > 0; 
} 

我有点恼火,虽然这样的品种一个非常具有误导性和无益的信息涵盖了原因。

+0

你已经回答了这个问题两次 - 这两个答案在我的代码库的不同部分与我有关。我对这个问题感到十分恼火。 – Miller

16

运行测试--sourcemaps=false不会使Karma默默无闻,但会给你一些关于错误的细节。

50

要了解什么是真正造成错误,禁用源地图:

ng test -sm=false 

然后您将看到一个更好的错误,例如“无法读取导致错误的实际源文件中未定义的”“属性'x'。出于某种原因,现在测试中存在一个源代码映射的错误,而您只是得到这个神秘的错误。

0

就我而言,我的模拟服务缺少ngOnInit方法中组件访问的一些公共变量。

5

添加到丹菲尔德的回答

这是1.2.2或更高版本Angular Cli版中的问题。用--sourcemaps=false运行你的测试,你会得到正确的错误信息。

ng test --sourcemaps=false

速记是这样的:

ng test -sm=false

这里查看详情:https://github.com/angular/angular-cli/issues/7296

相关问题