我有一个Angular组件和一个服务。在组件中,我有一个方法,它调用服务的一个方法。在组件测试中,我尝试为服务创建一个模拟,然后当我调用组件的方法时,我想检查是否从组件调用了服务方法。
组件:
export class TestComponent {
constructor(private testService: TestService) {}
edit(): void {
this.testService.getCase('id').subscribe(console.log);
}
}
服务:
@Injectable({
providedIn: 'root'
})
export class TestService {
constructor(
private http: HttpClient,
) { }
getCase(id: string): Observable<any> {
return this.http.get<any>(`url`);
}
}
和测试:
describe('TestComponent', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
const testServiceMock = jasmine.createSpyObj('TestService', ['getCase']);
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ TestComponent ],
providers: [
{ provide: TestService, useValue: testServiceMock },
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('expect service has been called', () => {
spyOn(component, 'edit');
component.edit();
expect(component.edit).toHaveBeenCalledTimes(1);
expect(testServiceMock.getCase).toHaveBeenCalled();
});
});
expect(testServiceMock.getCase).toHaveBeenCalled();
TestComponent expect service has been called FAILED Error: Expected spy TestService.getCase to have been called.
因为edit
方法是一个间谍,所以实际的实现永远不会被调用,所以getCase
间谍也永远不会被调用。为了解决这个问题,请使用edit
方法spy与callThrough()
。这将强制调用实际的实现。
spyOn(component,'edit').and.callThrough()
您需要将调用委托给实际实现:
spyOn(component, 'edit').and.callThrough();
https://jasmine.github.io/2.0/introduction section-Spies: _ % 3 ccode % 3 eand.callthrough % 3 c/代码% 3 e
您需要在第二个beforeEach()中创建注入服务,并将其设置为一个变量。
const testServiceMock = jasmine.createSpyObj('TestService',
['getCase']);
let testServiceSpy;
beforeEach(() => {
fixture = TestBed.createComponent(TestComponent);
testServiceSpy = TestBed.inject(TestService);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('expect service has been called', () => {
spyOn(component, 'edit');
component.edit();
expect(component.edit).toHaveBeenCalledTimes(1);
expect(testServiceSpy.getCase).toHaveBeenCalled();
});