【问题标题】:Karma testing in Angular 5. Failed: Http failure responseAngular 5 中的 Karma 测试。失败:Http 失败响应
【发布时间】:2018-01-06 11:09:56
【问题描述】:

应用组件:

ngOninit(){
    this.http.get('../assets/data/dummy.json').subscribe(result => {
      this.favorites = result;
    });
}

测试名称:AppComponent 应在 h1 标签中呈现标题

Karma 消息:失败:http://localhost:9876/assets/data/dummy.json 的 Http 失败响应:404 Not Found

如果我在get方法中将json的绝对路径设置为http://localhost:4200/assets/data/dummy.json,错误就消失了

【问题讨论】:

标签: unit-testing karma-jasmine angular5


【解决方案1】:

您的测试失败的原因是您的组件中的 ngOnInit() 正在进行实际的 http 调用以获取该资源 dummy.json

良好的单元测试实践通常表明您应该模拟应用程序的大部分部分,被测单元除外。这为您提供了更多控制权,并允许您的测试更好地解释发生故障时的错误所在。当我们对该资源使用实际的 http 调用并且测试失败时,我们不知道是因为未检索到资源还是因为标题未在 h1 标记中呈现。这两个问题彼此无关,应该在单独的测试用例中。为此,我们模拟了 http 调用,因此我们可以确保收到成功的响应,然后只关注标题。

为此,我们可以使用HttpClientTestingModule

这是app.component.ts 的示例,以反映您上面的示例:

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  template: `
    <h1>{{ title }} app is running!</h1>
  `
})
export class AppComponent implements OnInit {
  favorites: {};
  title = 'Demo';

  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.http.get('../assets/data/dummy.json').subscribe(result => {
      this.favorites = result;
    });
  }
}

为了让您的AppComponent should render title in a h1 tag 测试通过,这是您的规范文件app.component.spec.ts

import { TestBed, async } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';

import { AppComponent } from './app.component';

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
      imports: [ HttpClientTestingModule ]
    }).compileComponents();
  }));

  it('AppComponent should render title in a h1 tag', () => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector('h1').textContent).toContain('Demo app is running!');
  });
});

注意,我们所做的就是将HttpClientTestingModule 添加到TestBed.configureTestingModule({}) 的导入列表中。我们不需要做任何其他事情,当在此TestBed 中创建组件并请求HttpClient 时,TestBed 将为它提供来自HttpClientTestingModuleHttpClient。这将阻止您的所有请求实际发送,现在您的测试将通过。

这适用于您的情况,但现在它也允许您开始对 http 请求和响应执行测试。查看https://angular.io/guide/http#testing-http-requests 了解更多关于HttpClientTestingModule 和一般http 测试的信息。

【讨论】:

    猜你喜欢
    • 2019-04-22
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-22
    相关资源
    最近更新 更多