首页 > 解决方案 > 即使测试通过,Angular in-memory-web-api 方法总是在浏览器的控制台中返回 404 NotFound

问题描述

我是 Angular 单元测试的新手(使用 Jasmine 和 Karma)

我正在尝试为我的 httpService 创建一些测试,显然测试还可以。

在此处输入图像描述

但有时当我运行ng test或刷新浏览器时,我发现 3 个测试套件之一中的一个测试失败并显示以下消息:Uncaught [object Object] thrown.

在此处输入图像描述

另一个烦人的事情是,无论所有测试都通过还是失败,如果你检查浏览器的控制台,你总是会发现这个消息:

在此处输入图像描述

我将代码附加到一个 zip 文件中(上传到云端硬盘)。您只需要运行npm installnpm start.

我真的希望你能帮助我理解为什么这个测试表现得像俄罗斯轮盘赌。

标签: jasminekarma-runnerangular-test

解决方案


问题是calculator.component.spec.ts。你不是在嘲笑loanService它在哪里出去和HTTP打电话。您应该始终模拟外部服务。

更改calculator.component.spec.ts为:

import { NO_ERRORS_SCHEMA } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { CalculatorComponent } from './calculator.component';
import { LoanService } from '../loan.service';
import { Campaign } from '../campaign';
import { of } from 'rxjs/internal/observable/of';

describe('CalculatorComponent', () => {
  let component: CalculatorComponent;
  let fixture: ComponentFixture<CalculatorComponent>;
  let mockLoanService: any;

  beforeEach(async(() => {
    // mockLoanService object, first parameter ('loanService') is optional, second paramter => array of methods needing
    // mock for component
    mockLoanService = jasmine.createSpyObj('loanService', ['getCurrentCampaign', 'getMonthlyAmount']);
    TestBed.configureTestingModule({
      declarations: [ CalculatorComponent ],
      imports: [],
      // NO_ERRORS_SCHEMA to ignore child components, if you need the
      // painting of the DOM of the child components/directives, put them in declarations
      schemas: [NO_ERRORS_SCHEMA],
      providers: [
        FormBuilder,
        // provide the mock for LoanService
        { provide: LoanService, useValue: mockLoanService },
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(CalculatorComponent);
    component = fixture.componentInstance;
    // getCurrentCampaig is related to ngOnInit so we have to mock it
    mockLoanService.getCurrentCampaign.and.returnValue(of({
      id: 1,
      campaign_name: 'Donald Trump 2020',
      min_quota: -200000000,
      max_quota: 0,
      max_amount: 0,
      min_amount: 0,
      tea: 1,
      payment_date: new Date(),
      currency: 'Fake News',
    } as Campaign))
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

我在文件本身中写了一些评论。顺便说一句,Donald Trump 2020只是Fake News笑话,我没有政治背景,但我喜欢在我的单元测试中为其他开发人员写笑话:)。

一些注意事项:

1.) 每当您注入服务时,请始终模拟它。您正在单独测试组件和组件,您必须假设该服务将完成其工作,因为它已经在测试中。

2.) 退房NO_ERRORS_SCHEMA。它基本上会忽略 HTML 中不在declarations数组中的所有组件/指令。如果您正在编写一个测试,您单击子组件的按钮并且它会影响该组件,那么请在其中声明它declarations(基本上如果您需要子组件的实际实现,请声明它)。否则,使用NO_ERRORS_SCHEMA.

3.) 在我看来,在所有单元测试中导入SharedModule并不好。它会使你的单元测试变慢。取而代之的是,利用declarationsproviders为组件提供它需要的东西,而只是它需要的东西(而不是额外的东西)。

4.) PluralSight 中一个非常好的类,称为 Angular 中的单元测试。参加该课程,您将对单元/集成测试有更好的理解。也许购买 PluralSight 订阅或开始免费试用。


推荐阅读