Angular 5 中的 Karma 测试失败:Http 失败响应

san*_*dum 7 unit-testing karma-jasmine angular5

应用程序组件:

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

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

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

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

888*_*888 7

您的测试失败的原因是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;
    });
  }
}

Run Code Online (Sandbox Code Playgroud)

为了让您的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!');
  });
});
Run Code Online (Sandbox Code Playgroud)

请注意,为了使这项工作正常进行,我们将其添加到HttpClientTestingModuleTestBed.configureTestingModule({}). 我们不需要做任何其他事情,当在 this 中创建一个组件TestBed并请求一个 时HttpClient, theTestBed将为它提供HttpClient来自HttpClientTestingModule。这将阻止您的所有请求实际发送,现在您的测试将通过。

这适用于您的情况,但现在您还可以开始对 http 请求和响应执行测试。查看https://angular.io/guide/http#testing-http-requests以获取有关 http 测试的更多信息HttpClientTestingModule