gpt4 book ai didi

Angular 7 组件测试使用原始服务而不是模拟

转载 作者:太空狗 更新时间:2023-10-29 17:26:53 27 4
gpt4 key购买 nike

我正在尝试测试具有注入(inject)服务的组件。我想在我的测试中提供模拟服务。然而,测试使用的是原始服务而不是模拟服务(我知道这一点是因为我收到“没有 HttpClient 的提供者!”错误,而且我在测试中输出的原始服务中也有一个 console.log)。

我可以通过导入 HttpClientTestingModule 来修复错误,但这并不能修复使用原始服务而不是模拟服务的事实。

知道我做错了什么吗?

这是我的测试代码。 Angular 版本 7

import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { HelloWorldComponent } from '../../app/components/hello-world/hello-world.component';
import { HelloWorldService } from '../../app/services/hello-world.service';

describe('HelloWorldComponent', () => {

let component: HelloWorldComponent;
let fixture: ComponentFixture<HelloWorldComponent>;
let mockHelloWorldService;

beforeEach(() => {

mockHelloWorldService = jasmine.createSpyObj(['getHelloWorld']);

TestBed.configureTestingModule({
imports: [],
declarations: [HelloWorldComponent],
providers: [
[{ provide: HelloWorldService, useClass: mockHelloWorldService }]
]
}).compileComponents();

fixture = TestBed.createComponent(HelloWorldComponent);
component = fixture.componentInstance;
fixture.detectChanges();

});

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

});

更新

我已经尝试过 overrideProvider,但现在我收到了“无法读取未定义的‘订阅’属性”错误,这感觉像是进步了...

这是我的测试代码

import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { HelloWorldComponent } from '../../app/components/hello-world/hello-world.component';
import { HelloWorldService } from '../../app/services/hello-world.service';
import { of } from 'rxjs';

describe('HelloWorldComponent', () => {

let component: HelloWorldComponent;
let fixture: ComponentFixture<HelloWorldComponent>;
let mockHelloWorldService;

beforeEach(async(() => {
mockHelloWorldService = jasmine.createSpyObj(['getHelloWorld']);
TestBed.configureTestingModule({
imports: [],
declarations: [HelloWorldComponent]
});
TestBed.overrideProvider(HelloWorldService, { useValue: mockHelloWorldService });
TestBed.compileComponents();

}));

beforeEach(() => {
fixture = TestBed.createComponent(HelloWorldComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

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

这是我的组件

import { Component, OnInit } from '@angular/core';
import { HelloWorldService } from '../../services/hello-world.service';

@Component({
selector: 'app-hello-world',
templateUrl: './hello-world.component.html',
providers: [HelloWorldService]
})
export class HelloWorldComponent implements OnInit {

helloWorldMessage: any;
constructor(private helloWorldService: HelloWorldService) { }

ngOnInit() {
this.getHelloWorldMsg();
}

getHelloWorldMsg() {
this.helloWorldService
.getHelloWorld()
.subscribe((data) => {
this.helloWorldMessage = data;
}, err => this.handleErrorResponse('There was a problem loading the hello world message', err));
}

handleErrorResponse(errorMsg: string, error?: any) {
console.log("There was a problem getting the message");
}
}

这是我的服务

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

import { environment } from '../../environments/environment';

@Injectable()
export class HelloWorldService {
constructor(private http: HttpClient) { }

getHelloWorld(): Observable<any> {
console.log("Why is the test coming here when I provide a mock?");
var getHelloWorldApiUrl = environment.apiUrl + "/api/v1.0/helloworld/GetHelloWorldMessageAuth";
return this.http
.get(getHelloWorldApiUrl);
}
}

最佳答案

我在上面的代码中看到两个问题:

  • 您的 TestBed 的提供程序数组中有一组额外的方括号。我不认为这是一个主要问题,它只是在语义上不正确。
  • 当您在 providers 数组中提供 HelloWorldService 时,您指定了 useClass,但提供了一个对象(即 jasmine.createSpyObj() 产生),因此您应该改为指定 useValue

希望对您有所帮助。

更新:

好的,您已经取得了长足的进步!您纠正了我上面概述的两个问题,按照我在对另一个答案的评论中建议的那样在 compileComponents() 之前完成了 overrideProvider() 并包装了 beforeEach()async() 中。

我要求查看所有其他代码的原因是我可以快速将其放在下面的 StackBlitz 中用于检测。正如您在 StackBlitz 中看到的那样,测试现已通过。

我只在 beforeEach() 中添加了一行来声明一个来自你的 spy 的 returnValue,这样你的组件中的 subscribe 就有一个 Observable 可以订阅:

mockHelloWorldService.getHelloWorld.and.returnValue(of('Test Message'));

我在调用 fixture.detectChanges() 之前添加了它,因为这将调用 ngOnInit(),并且 spy 需要在执行 之前设置返回值ngOnInit() 以便它能够正确执行并且不会给您带来您所看到的错误。

我还在规范中添加了一行来展示如何测试 Observable 的结果是否正确设置为您的组件变量:

expect(component.helloWorldMessage).toEqual('Test Message');

请注意,在组件声明的提供程序数组中指定 HelloWorldService 会使测试变得非常复杂。如果您改为在 root 中将此服务作为单例提供,这将大大简化事情,包括您的测试方式。请参阅 Official Docs 中的详细信息.

关于Angular 7 组件测试使用原始服务而不是模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54036099/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com