我正在尝试测试具有注入服务的组件。我想在我的测试中提供模拟服务。然而,测试使用原始服务而不是模拟服务(我知道这一点是因为我收到“没有 HttpClient 的提供程序!”错误,而且我在测试中输出的原始服务中有一个 console.log)。
我可以通过导入 HttpClientTestingModule 来修复错误,但这并不能解决使用原始服务而不是模拟服务这一事实。
有什么想法我做错了吗?
这是我的测试代码。角度版本 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();
});
});
UPDATE
我已经尝试过 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 的提供者数组中有一组额外的方括号。我认为这不是一个主要问题,它只是语义上不正确。
- 当您提供
HelloWorldService
在提供者数组中,您已指定useClass
,但提供了一个对象(这就是jasmine.createSpyObj()
产生),所以你应该指定useValue
.
我希望这有帮助。
Update:
好吧,你已经走了很长的路了!您纠正了我上面概述的两个问题,并完成了overrideProvider()
之前compileComponents()
正如我在对另一个答案的评论中建议的那样beforeEach()
里面一个async()
.
我要求查看所有其他代码的原因是这样我可以快速将其放在下面堆栈闪电战 https://stackblitz.com/edit/stackoverflow-q-54036099?file=app%2Fhello-world.component.spec.ts供测试用。正如您在 StackBlitz 中看到的,测试现已通过。
我只在其中添加了一行beforeEach()
声明来自您的间谍的 returnValue,以便您的组件中的订阅有一个可订阅的 Observable:
mockHelloWorldService.getHelloWorld.and.returnValue(of('Test Message'));
我在调用之前添加了这个fixture.detectChanges()
因为这会调用ngOnInit()
,并且间谍程序需要在执行之前设置返回值ngOnInit()
这样它就会正确执行并且不会给您所看到的错误。
我还在规范中添加了一行,以展示如何测试 Observable 的结果是否正确设置为组件变量:
expect(component.helloWorldMessage).toEqual('Test Message');
请注意,通过在组件声明的providers数组中指定HelloWorldService,您的测试会显着复杂化。如果您将此服务作为根中的单例提供,这将大大简化事情,包括您的测试方式。详情请参阅官方文档 https://angular.io/guide/singleton-services.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)