単体テストファイルの1つで、同じサービスを異なるモックで数回モックする必要があります。
import { MyService } from '../services/myservice.service';
import { MockMyService1 } from '../mocks/mockmyservice1';
import { MockMyService2 } from '../mocks/mockmyservice2';
describe('MyComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
MyComponent
],
providers: [
{ provide: MyService, useClass: MockMyService1 }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MapComponent);
mapComponent = fixture.componentInstance;
fixture.detectChanges();
});
describe('MyFirstTest', () => {
it('should test with my first mock', () => {
/**
* Test with my first mock
*/
});
});
describe('MySecondTest', () => {
// Here I would like to change { provide: MyService, useClass: MockMyService1 } to { provide: MyService, useClass: MockMyService2 }
it('should test with my second mock', () => {
/**
* Test with my second mock
*/
});
});
});
関数 overrideProvider が存在することがわかりましたが、テストで使用することができませんでした。 「it」で使用しても、プロバイダーは変更されません。この関数が呼び出される例を見つけることができませんでした。適切に使用する方法を説明してもらえますか?または、それを行う別の方法がありますか?
サービスがパブリックプロパティとして注入される場合、例:
@Component(...)
class MyComponent {
constructor(public myService: MyService)
}
次のようなことができます:
it('...', () => {
component.myService = new MockMyService2(...); // Make sure to provide MockMyService2 dependencies in constructor, if it has any.
fixture.detectChanges();
// Your test here...
})
挿入されたサービスがプライベートプロパティに格納されている場合、(component as any).myServiceMockMyService2 = new MockMyService2(...);
TSをバイパスします。
きれいではありませんが、動作します。
はどうかと言うと TestBed.overrideProvider
、私はそのアプローチに運がなかった(うまくいけばもっといいだろう):
it('...', () =>{
TestBed.overrideProvider(MyService, { useClass: MockMyService2 });
TestBed.compileComponents();
fixture = TestBed.createComponent(ConfirmationModalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
// This was still using the original service, not sure what is wrong here.
});
angular 6の時点で、overrideProvider
がuseValue
プロパティで動作することに気付きました。
_class MockRequestService1 {
...
}
class MockRequestService2 {
...
}
_
次に、TestBedのように記述します。
_// example with injected service
TestBed.configureTestingModule({
// Provide the service-under-test
providers: [
SomeService, {
provide: SomeInjectedService, useValue: {}
}
]
});
_
そして、プロバイダーをオーバーライドしたいときはいつでも使用するだけです:
_TestBed.overrideProvider(SomeInjectedService, {useValue: new MockRequestService1()});
// Inject both the service-to-test and its (spy) dependency
someService = TestBed.get(SomeService);
someInjectedService = TestBed.get(SomeInjectedService);
_
beforeEach()
関数内に配置するか、it()
関数に配置します。
参照用に、annynoneがこの問題を満たしている場合。
使ってみた
_TestBed.overrideProvider(MockedService, {useValue: { foo: () => {} } });
_
動作していませんでした、まだ元のサービスがテストに挿入されました(_providedIn: root
_で)
テストでは、aliastoimportOtherService
:を使用しました。
_import { OtherService } from '@core/OtherService'`
_
一方、サービス自体にはimportとrelative pathがありました:
_import { OtherService } from '../../../OtherService'
_
testとserviceの両方に同じインポートTestBed.overrideProvider()
が有効になり始めました。
Env:Angular 7ライブラリ-アプリケーションとjestではありません
これはちょうど私のために働いた(Angular 7.x):
imports: [ MyCoreModule.forRoot()],
providers: [{provide: LoginService, useValue: new LoginServiceMock()}]
ログインサービスはMyCoreModuleの一部ですが、モックプロバイダーでオーバーライドできます。また、useValueを使用している場合は、new yourService()を忘れないでください
{ provide: MyService, useValue: new MockMyService1() }