角度测试失败,无法在“ XMLHttpRequest”上执行“发送”


145

我正在尝试测试我的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>) {
  }
}

但是,一个简单的“应该创建”测试将引发此神秘错误...

NetworkError:无法在'XMLHttpRequest'上执行'send':无法加载'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
我遇到了同样的问题,并发现了与您相同的帖子。我能够找到解决方案。我最终发布了另一个问题,但您可以在这里看看:stackoverflow.com/a/45419372/6739517 希望对您有所帮助!
Niles Tanner

Answers:


342

这是新的Angular Cli的问题。使用进行测试,--sourcemaps=false您将获得正确的错误消息。

在此处查看详细信息:https : //github.com/angular/angular-cli/issues/7296

编辑:

简写为:

ng test -sm=false

从角度6开始,命令为:

ng test --source-map=false


19
你是绝对的英雄。由于缺少Angular单元测试错误消息的信息,我沮丧地将头撞到了墙上,直到发现这一点。多谢。
艾伦·史密斯

1
这个答案确实挽救了我的一天!我花了整整一天的时间来解决这个问题之后,我几乎要放弃开发了,只是为了避免成为失败的开发者
user1806692

今天,我遇到了以下错误消息:HeadlessChrome 65.0.3325(Mac OS X 10.13.4)错误{“ message”:“脚本错误。\ nat:0:0”,“ str”:“脚本错误。\ nat:0 :0“}并删除--sourcemap = false将显示更多信息。
penghui

11
ng test --source-map = false ...适用于Angular CLI 6
danday74 '18

@ danday74 FTW!在编写了复杂的测试文件之后,挂上它是残酷的。
布拉德·理查森

21

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

ng test --source-map=false

也许它将帮助某人:)。


8

对于我的情况,存在模拟数据问题,对于Array,我是string从模拟返回。

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

错误消息确实使人分心,没有告诉实际错误。Running ng test --source=false指出了正确的错误和界线,并帮助我快速修复了它。

当您模拟数据不完整或不正确时,通常会发生这种情况。


7

您可以在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 : //stackoverflow.com/a/45570571/7085047我的问题出在我的ngOnInit。我正在调用一个模拟的摇摇欲坠生成的REST控制器代理。它返回null,而我正在订阅该null,这是行不通的...

错误又回来了:

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);

然后将实例添加到测试的provider数组中,如下所示:

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

如果您有新问题,请点击 提问”按钮提问。如果它有助于提供上下文,请包括此问题的链接。- 评分
安东Balaniuc

似乎我的症状与OP相同,因此我认为人们可能会发现对我有用的修复方法...
Datum Geek

3

这可能与Chrome隐藏实际的测试错误有关。测试区域会混淆一些无法加载的模拟http工厂,因此这将报告错误。该错误最有可能出现在ngOnInit区域附近,在该区域中某个对象就是期望的子对象,并且未定义它们。

要尝试找出错误的根源,请暂时切换到PhantomJS,它似乎受这些初始化错误的影响较小,并且有望将实际错误报告给您。我几次发现初始化时预期的对象未完成。IE浏览器:

    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;

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

更正该对象后,PhantomJS可以完成操作,Chrome也可以继续进行下一个测试。

除此之外,我还没有找到从Chrome移除问题的解决方案。与以往一样,尝试采用“删除代码,直到错误消失”的策略来追查错误。

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


2

我也有这个错误,要说的是实话实话。

这与通过我的服务进行的HTTP调用有关

我使用2种方法使用myService.ts

get();
getAll();

我在嘲笑此服务:mockMyService.ts

错误在这里是因为我的组件正在使用getAll()方法,而我忘记在模拟我的服务中实现该方法,因此我只添加了该方法:

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

错误不见了:)


2

我遇到了同样的问题,并且发现要解决此问题,您必须在beforeEach方法中设置组件的输入,如下所示:

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

这肯定会解决您的问题。


1

在我的情况下,罪魁祸首被observable.timeout(x).retry(y)应用到服务类级别上返回的Observable的某个位置,然后再次应用到使用该服务的组件中。

直到angular-cli 1.4之前,一切都可以在浏览器中正常工作。然后在Karma测试期间开始失败(出现如此愚蠢的错误)。解决方案当然是整理这些超时/重试操作员。


1

对我来说,当我的测试中的模拟错误时,会显示此消息:通常,您在测试引导程序中提供了模拟服务。如果您的模拟不完整或虚假,则角度返回此愚蠢错误。

有关我的案件的更多信息,请点击此处


0

我要做的是:

添加console.log(),在ngOnint()中一行接一行,找出行进距离,然后检查它不会通过的行。

例如:

ngOnInit() {
    this.route.paramMap
        .switchMap(params => {
            this.busy = true;
            this.updateErrors(null);

            console.log(params);

            **const id = params.get('id');**
            console.log(id);

            if (id === 'new') {
                this.editMode = true;
                return Observable.of(GroupComponent.newGroup());
            }
            return this.apiService.getGroup(id);
        })
    }

这在我的测试中失败,并在这篇文章中出现了相同的错误。如上所示,我有两个console.logs。第一个通过了thorugh,但是第二个没有通过。所以我意识到问题就在网上 const id = params.get('id');。然后我修好了

希望这会帮助某人。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.