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

Posted

技术标签:

【中文标题】Angular 测试失败,无法在“XMLHttpRequest”上执行“发送”【英文标题】:Angular tests failing with Failed to execute 'send' on 'XMLHttpRequest' 【发布时间】:2018-01-06 00:48:31 【问题描述】:

我正在尝试测试我的 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”上执行“发送”:无法加载“ng:///DynamicTestModule/module.ngfactory.js”。

所以我发现了this 问题,这表明问题在于组件具有未设置的@Input)_ 参数,但是,如果我像这样修改我的测试:

  it('should create', inject([CellComponent], (cmp: CellComponent) => 
    cmp.dep = '';
    cmp.embedded = false;
    cmp.dashboard = false;
    expect(cmp).toBeTruthy();
  ));

然后我仍然遇到同样的问题,同样,如果我从组件中删除 @Input() 注释,仍然没有区别。我怎样才能让这些测试通过?

【问题讨论】:

为了创建组件,您需要提供所有依赖项。你能展示你所有的测试设置吗?我将尝试在plnkr 上重现该问题 我遇到了同样的问题,并找到了与您相同的帖子。我能够找到解决方案。我最终发布了另一个问题,但您可以在这里查看:***.com/a/45419372/6739517 希望对您有所帮助! 看到这个:github.com/angular/angular-cli/issues/7296 【参考方案1】:

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

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

编辑:

这个的缩写是:

ng test -sm=false

从 Angular 6 开始,命令为:

ng test --source-map=false

【讨论】:

你绝对的英雄。由于缺少来自 Angular 单元测试错误消息的信息,我感到很沮丧,直到我发现了这一点。非常感谢。 这个答案真的救了我一天!在花了一整天的时间试图解决这个问题之后,我几乎要放弃一般的开发了,这样我就可以不再成为构建失败的人了 今天我遇到了这个错误消息: HeadlessChrome 65.0.3325 (Mac OS X 10.13.4) ERROR "message": "Script error.\nat :0:0", "str": "脚本错误。\nat :0:0" 删除 --sourcemap=false 会显示更多信息。 ng test --source-map=false ... 适用于 Angular CLI 6 @danday74 FTW!在编写了复杂的测试文件之后,被挂断是很残酷的。【参考方案2】:

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

ng test --source-map=false

也许它会帮助某人:)。

【讨论】:

【参考方案3】:

就我而言,存在模拟数据问题,如果是 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 指出了正确的错误和行,并帮助我快速修复它。

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

【讨论】:

【参考方案4】:

您可以在 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();  
);

【讨论】:

【参考方案5】:

正如上面的建议:https://***.com/a/45570571/7085047 我的问题出在我的ngOnInit 中。我正在调用一个模拟 swagger 生成的 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);

然后像这样将实例添加到测试的 providers 数组中:

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

【讨论】:

如果您有新问题,请点击 按钮提出问题。如果有助于提供上下文,请包含指向此问题的链接。 - From Review 似乎我的症状与 OP 相同,所以我认为人们可能会发现对我有用的修复...【参考方案6】:

我遇到了同样的问题,我发现要修复它,您必须在方法 beforeEach 中为组件设置输入,如下所示:

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

这肯定会解决您的问题。

【讨论】:

【参考方案7】:

这可能与 Chrome 隐藏实际测试错误有关。测试区域会混淆一些无法加载的模拟 http 工厂,因此这就是它会报告的错误。错误最有可能出现在 ngOnInit 区域附近,例如,该对象需要子对象但未定义。

要尝试找出错误的根源,请暂时切换到 PhantomJS,它似乎受这些初始化错误的影响较小,这有望向您报告实际错误。有几次我发现初始化时预期的对象不完整。 即:

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

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

更正对象允许 PhantomJS 完成,Chrome 也可以继续下一个测试。

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

更新:请注意,这是一个相当古老的答案,我不建议再使用 PhantomJS (EOL)。浏览器测试报告已经好很多了,如果 Chrome 让你感到悲伤,那么试试 Firefox,它现在也能很好地运行测试。

【讨论】:

【参考方案8】:

我也有这个错误,说实话是相当不健谈的。

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

我将 myService.ts 与 2 种方法一起使用

get();
getAll();

我在嘲笑这个服务:mockMyService.ts

错误就在这里,因为我的组件使用了我忘记在 mockMyService 中实现的 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);

错误消失了 :)

【讨论】:

【参考方案9】:

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

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

【讨论】:

【参考方案10】:

对我来说,当我的测试中的模拟错误时会出现此消息:通常您在测试引导程序中提供 mockService。如果你的模拟不完整或虚假,那么角度返回这个愚蠢的错误。

关于我的案例的更多信息here

【讨论】:

【参考方案11】:

我要做的是:

在 ngOnint() 中逐行添加 console.log() 并找出它走了多远,然后检查它不会通过的行。

例如:

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。第一个通过了,第二个没有。所以我意识到问题出在 const id = params.get('id'); 线上,我修复了它。

希望这会对某人有所帮助。

【讨论】:

以上是关于Angular 测试失败,无法在“XMLHttpRequest”上执行“发送”的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS Jasmine 测试失败:无法实例化模块

Angular 4 - 请求的资源上不存在“Access-Control-Allow-Origin”标头

Angular2 - 在测试中模拟 RouteParams

单元测试时,Angular RC 5 中无法解析路由器的所有参数:(?, ?, ?, ?, ?, ?, ?)

在 Angular 8 (Karma 4.1.0) 升级后,在 Angular 7 (Karma 2.0.4) 中成功完成的 Karma 测试失败

带有 viewchild 和指令的 Angular 组件测试