angularサービスを単体テストしようとして問題が発生しました。このサービスが、挿入されている別のサービスを適切に呼び出していることを確認したいのですが。
ServiceInjectedを注入するこのServiceToTestがあるとします。
ServiceToTest .service.ts
@Injectable()
export class ServiceToTest {
constructor(private _si: ServiceInjected) {}
public init() {
this._si.configure();
}
}
ServiceInjected.service.ts
@Injectable()
export class ServiceInjected {
constructor() {}
public configure() {
/*Some actions*/
}
}
これらのサービスを使用して、単体テストを作成します。
const serviceInjectedStub = {
configure(): void {}
}
describe('ServiceToTest service Test', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ServiceToTest ,
{ provide: ServiceInjected, useValue: serviceInjectedStub }]
});
});
it('should be initialize the service injected', inject([ServiceToTest],
(tService: ServiceToTest) => {
spyOn(serviceInjectedStub, 'configure');
tService.init();
expect(serviceInjectedStub.configure).toHaveBeenCalled();
}));
テストは成功するはずですが、次のエラーが表示されます。
スパイ構成が呼び出されていることが予期されていました。
一方、注入されたサービスを次のようにパブリックに設定すると、問題なく動作します。
private _si: ServiceInjected by public si: ServiceInjected
TestBedに関連付けられているサービスをスパイすることはありません。テストベッドからサービスを入手する
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ServiceToTest ,
{ provide: ServiceInjected, useValue: serviceInjectedStub }]
});
injectedService = TestBed.get(ServiceInjected);
});
そしてそれをテストする
spyOn(injectedService, 'configure').and.returnValue(/* return same data type here */);
// ...
expect(injectedService.configure).toHaveBeenCalled();
または、jasmine.createSpyObj
とuseValue
を次のように提供します。
describe('YourComponent', () => {
let serviceInjectedSpy: jasmine.SpyObj<ServiceInjected>;
beforeEach(async(() => {
// notice here
serviceInjectedSpy = jasmine.createSpyObj('ServiceInjected', ['configure']);
TestBed.configureTestingModule({
declarations: [YourComponent],
providers: [
{provide: ServiceInjected, useValue: serviceInjectedSpy}
],
imports: [
...
]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(YourComponent);
component = fixture.componentInstance;
});
});
it('should assert my test', () => {
serviceInjectedSpy.configure.and.returnValue(/* what you want */);
component.init();
expect(serviceInjectedSpy.configure).toHaveBeenCalled();
});
});
これを使って:
spyOn(serviceInjectedStub、 'configure')。and.returnValue(config); //設定はモックです
次のようなモックサービスを使用する必要があります。
class MockAuthService extends AuthService {
isAuthenticated() {
return 'Mocked';
}
}
このようにして、テストしていないサービスを制御し、他のサービスに集中できます。
ここで、サービスが正しく呼び出されているかどうかを確認するには、モックサービスが呼び出されるたびにtrueになるモック変数を追加できます。