Jasmine Angular in-memory web api方法始终在浏览器中返回404NotFound';即使测试通过了,也要访问控制台

Jasmine Angular in-memory web api方法始终在浏览器中返回404NotFound';即使测试通过了,也要访问控制台,jasmine,karma-runner,angular-test,Jasmine,Karma Runner,Angular Test,我不熟悉Angular的单元测试(使用Jasmine和Karma) 我正在尝试为我的httpService创建一些测试,显然测试还可以 但有时,当我运行ng test,或刷新浏览器时,我发现3个测试套件中的一个测试失败,并显示以下消息:Uncaught[object object]抛出 另一件恼人的事情是,无论所有测试是否通过或其中任何一项失败,如果您检查浏览器的控制台,您总是会发现以下消息: 。您只需运行npm安装和npm启动 我真的希望你能帮助我理解为什么这个测试的行为像俄罗斯轮盘赌

我不熟悉Angular的单元测试(使用Jasmine和Karma)

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

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

另一件恼人的事情是,无论所有测试是否通过或其中任何一项失败,如果您检查浏览器的控制台,您总是会发现以下消息:

。您只需运行
npm安装
npm启动


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

问题是
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();
  });
});
从'@angular/core'导入{NO_ERRORS_SCHEMA};
从'@angular/forms'导入{FormBuilder};
从“@angular/core/testing”导入{async,ComponentFixture,TestBed};
从“./calculator.component”导入{CalculatorComponent};
从“../loan.service”导入{LoanService};
从“../Campaign”导入{Campaign};
从“rxjs/internal/observable/of”导入{of};
描述('CalculatorComponent',()=>{
let组件:计算器组件;
let夹具:组件夹具;
让mockLoanService:任何;
beforeach(异步(()=>{
//mockLoanService对象,第一个参数('loanService')是可选的,第二个参数=>需要的方法数组
//组件模拟
mockLoanService=jasmine.createSpyObj('loanService',['getCurrentCampaign','GetMonthlyMount']);
TestBed.configureTestingModule({
声明:[计算器组件],
进口:[],
//如果需要,则无\u错误\u架构可忽略子组件
//绘制子组件/指令的DOM,将它们放入声明中
模式:[无错误模式],
供应商:[
造模工,
//提供模拟贷款服务
{provide:LoanService,useValue:mockLoanService},
]
})
.compileComponents();
}));
在每个之前(()=>{
fixture=TestBed.createComponent(计算器组件);
组件=fixture.componentInstance;
//getCurrentCampaig与ngOnInit有关联,所以我们不得不嘲笑它
mockLoanService.getCurrentCampaign.and.returnValue(共({
id:1,
竞选名称:“唐纳德·特朗普2020”,
最低限额:-200000000,
最大配额:0,
最高金额:0,
最低金额:0,
茶:1,,
付款日期:新日期(),
货币:"假新闻",,
}(作为竞选活动)
fixture.detectChanges();
});
它('应该创建',()=>{
expect(component.toBeTruthy();
});
});
我在文件中写了一些评论。顺便说一句,
Donald Trump 2020
假新闻
只是笑话,我没有政治背景,但我喜欢在我的单元测试中为其他开发人员写笑话:)

一些注意事项:

1.)无论何时注入服务,都要对其进行模拟。当您单独测试组件和组件时,您必须假设服务将完成其工作,因为它已经在测试中

2.)签出
无错误\u模式
。它基本上会忽略HTML中不在
声明
数组中的所有组件/指令。如果您正在编写一个测试,其中您单击了子组件的按钮,并且该按钮会影响该组件,那么请在
声明中声明它(基本上,如果您需要子组件的实际实现,请声明它)。否则,请使用
NO\u ERRORS\u SCHEMA

3.)在我看来,在所有单元测试中导入
SharedModule
并不好。这会使单元测试变慢。相反,利用
声明
提供者
,为组件提供它需要的东西和它需要的东西(而不是额外的东西)

4.)PluralSight中有一门非常好的课程,叫做Angular中的单元测试。 参加该课程,您将更好地理解单元/集成测试。可能购买PluralSight的订阅或开始免费试用