Angular测试失败,出现“在XMLHttpRequest上执行'send'时失败”的错误。

154

我正在尝试测试我的Angular 4.1.0组件 -

export class CellComponent implements OnInit {
  lines: Observable<Array<ILine>>;
  @Input() dep: string;
  @Input() embedded: boolean;
  @Input() dashboard: boolean;
  constructor(
    public dataService: CellService,
    private route: ActivatedRoute,
    private router: Router, private store: Store<AppStore>) {
  }
}

然而,一个简单的“should create”测试会产生以下晦涩的错误信息:

NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'ng:///DynamicTestModule/module.ngfactory.js'.

因此,我发现了这个问题,它表明组件具有未设置的@Input参数。如果我像下面这样修改我的测试:
  it('should create', inject([CellComponent], (cmp: CellComponent) => {
    cmp.dep = '';
    cmp.embedded = false;
    cmp.dashboard = false;
    expect(cmp).toBeTruthy();
  }));

如果我仍然遇到同样的问题,同样地,如果我从组件中删除@Input()注释,也没有任何区别。我该如何使这些测试通过?


1
为了创建组件,您需要提供所有依赖项。 你能展示一下你的测试设置吗?我会尝试在plnkr上重现这个问题。 - Aleksandr Petrovskij
1
我曾经遇到过同样的问题,并找到了你所看到的帖子。最终我找到了解决方案。我最终在另一个问题上发布了答案,但你可以在这里查看:https://dev59.com/RFcP5IYBdhLWcg3wiqZr#45419372 希望能帮到你! - Niles Tanner
{btsdaf} - titusfx
11个回答

355
这是新版Angular Cli的一个问题。使用--sourcemaps=false运行测试,您将获得正确的错误消息。
详细信息请参见:https://github.com/angular/angular-cli/issues/7296 编辑:
简写命令为: ng test -sm=false 自Angular 6起,命令为: ng test --source-map=false

20
你真是个英雄。在 Angular 单元测试错误信息中没有得到足够的信息让我感到非常沮丧,直到我发现了这篇文章。非常感谢。 - Alan Smith
1
这个回答真的救了我的一天!我整天整夜都在努力修复这个问题,以此来避免成为那个导致构建失败的人。谢谢你! - user1806692
今天我遇到了这个错误信息:HeadlessChrome 65.0.3325 (Mac OS X 10.13.4) ERROR { "message": "Script error.\nat :0:0", "str": "Script error.\nat :0:0" }移除 --sourcemap=false 可以显示更多信息。 - Peng-Watcher37-Link37
11
在Angular CLI 6中,“ng test --source-map=false”是有效的。 - danday74
不适用于angular cli 6.0.8。 相反,请使用ng test --source-map=false。 - Amir Khademi
显示剩余2条评论

21

我在使用Angular CLI 6时也遇到了同样的问题,我使用了这个标签来获取正确的错误消息:

ng test --source-map=false

也许这会对某些人有所帮助 :)


9

在我的情况下,模拟数据存在问题,对于Array,我从模拟中返回了一个string

someApi = fixture.debugElement.injector.get(SomeApi);
spyOn(someApi, 'someMethod')
  .and.returnValue(Observable.of('this is not a string but array'));

这个错误信息真的很分散注意力,而且没有告诉实际的错误。运行 ng test --source=false 指向了正确的错误和行数,帮助我快速修复了它。

很多时候,当你模拟数据不完整或不正确时会发生这种情况。


8
您可以在 component.ts 中设置 input() 属性的默认值。
@Input() tableColumns: Array<any> = [];  
@Input() pageObj: any = '';

修改您的component.spec.ts文件,按以下方式进行:

beforeEach(() => {  
   fixture = TestBed.createComponent(MyComponent);  
   component = fixture.componentInstance;  
   component.tableColumns = [];  
   component.pageObj = '';  
   fixture.detectChanges();  
});

4
如上面建议的那样:在此处https://dev59.com/WFcO5IYBdhLWcg3wsTnM#45570571,我的问题出现在我的ngOnInit里。我调用了一个模拟的 swagger 生成的 REST 控制器代理。它返回了空值,然后我订阅了这个空值,这样是行不通的...

错误信息如下:

Failed to load ng:///DynamicTestModule/MockNodeDashboardComponent_Host.ngfactory.js: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

我使用了ts-mockito修复了这个问题:https://github.com/NagRock/ts-mockito

我添加了代码来创建一个模拟实例,就像这样:

import { mock, instance, when } from 'ts-mockito';
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';
import { MockScenario } from './vcmts-api-client/model/MockScenario';

const MockVcmtsnodemockresourceApi: VcmtsnodemockresourceApi = mock(VcmtsnodemockresourceApi);
const obs = Observable.create((observer: Observer<MockScenario[]>) => {
  observer.next(new Array<MockScenario>());
  observer.complete();
});
when(MockVcmtsnodemockresourceApi.getMockScenariosUsingGET()).thenReturn(obs);
const instanceMockVcmtsnodemockresourceApi: VcmtsnodemockresourceApi = instance(MockVcmtsnodemockresourceApi);

然后像这样将实例添加到测试的提供程序数组中:

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      ...
      providers: [
        ...
        { provide: VcmtsnodemockresourceApi, useValue: instanceMockVcmtsnodemockresourceApi },
        ...
      ]        
    }).compileComponents();
  }));

如果您有新的问题,请通过单击提问按钮来提出。如果它有助于提供上下文,请包含此问题的链接。- 来自审核 - Anton Balaniuc
似乎我的症状和原帖作者一样,所以我认为大家可能会发现对我有效的解决方法很有用... - Datum Geek

4
这可能与Chrome隐藏实际测试错误有关。测试区域会使某些模拟http工厂混淆,导致无法加载,因此这是它报告的错误。最可能的错误出现在ngOnInit区域,其中一个对象期望子对象但未定义。
为了尝试找到错误的根源,请暂时切换到PhantomJS,它似乎不太容易受到这些初始化错误的影响,这将希望向您报告实际错误。我发现有几种情况是在初始化时预期的对象不完整。
例如:
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;

    component.object = {}
// should be:
    component.object = {"innerObjectThatIsNeeded" : []}

修正对象使PhantomJS能够完成测试,并使Chrome继续进行下一个测试。

除此之外,我没有看到从Chrome中解决该问题的解决方案。像往常一样,尝试采用“删除代码,直到错误消失”的策略来追踪错误。

更新:请注意,这是一个相当旧的答案,我不建议再使用PhantomJS(已停用)。 浏览器测试报告变得更加完善,如果Chrome给您带来麻烦,请尝试Firefox,现在它也可以很好地运行测试。


3

我曾经遇到过同样的问题,后来发现可以通过在beforeEach方法中设置组件的输入来解决这个问题,具体如下:

beforeEach(() => {
    fixture = TestBed.createComponent(CellComponent );
    cmp = fixture.debugElement.componentInstance;
    cmp.dep = '';
    cmp.embedded = false;
    cmp.dashboard = false;
    fixture.detectChanges();
});

这一定会解决你的问题。

2

我也遇到了这个错误,但实话说它并不是很具体。

与我的服务相关的 HTTP 调用有关。

我使用 myService.ts 有 2 个方法。

get();
getAll();

我正在模拟这个服务: mockMyService.ts

错误出在这里,因为我的组件正在使用getAll()方法,而我忘记在mockMyService中实现它,所以我只需添加该方法:

private mockObjects = [
{
  'id': '1',
  'champ1': 'TECH',
  'champ2': 2,
  'champ3': 'Data bidon'
},
{
  'id': '2',
  'champ1': 'TECH',
  'champ2': 2,
  'champ3': 'Data au pif'
},
{
  'id': '3',
  'champ1': 'FUNC',
  'champ2': 3,
  'champ3': 'Data quelconque'
},
 ];

getAll(): Observable<any> {
  return Observable.of(this.mockObjects);
}

错误已经消失:)


1
在我的情况下,罪魁祸首是应用于服务类级别上返回的Observable的observable.timeout(x).retry(y),然后又在使用该服务的组件中应用了一次。在angular-cli 1.4之前,一切都在浏览器中正常工作。然后在Karma测试期间开始失败(出现如此愚蠢的错误)。解决方案当然是整理这些timeout/retry操作符。

1

当我的测试中使用的模拟数据不完整或者为假时,我会看到这个消息:通常你在测试启动时提供mockService。如果你的模拟数据不完整或者为假,那么angular就会返回这个愚蠢的错误。

更多关于我的情况的信息在此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接