Ana içeriğe geç

Mock Modüllerindeki İç ve Dış Yapılar

Modülün nasıl sahte (mock) edilmesi gerektiğini anlamanın önemli bir noktası vardır.

Hayal edelim ki, bir modülümüz var ve tanımı şöyle görünüyor:

@NgModule({
imports: [ExternalModule],
declarations: [
MyComponent,
InternalDirective,
],
exports: [MyComponent],
})
class InternalModule {}

Açıklama

Modülde iki tanım vardır: MyComponent ve InternalDirective.
Bunlar birbirlerini kullanabilir, çünkü aynı modülde tanımlanmışlardır.

ipucu

İhracatları kontrol ettiğimizde, yalnızca MyComponent'in dışarı aktarıldığını görüyoruz.
Bu, bir modül InternalModule'ü içe aktardığında, InternalDirective'e doğrudan erişimin olmadığı anlamına gelir.

Bu, bir Angular uygulaması inşa ediyorsak sorun değil. InternalDirective içsel bir şeydir ve InternalModule dışında uygulamamızda kullanılmasına gerek yoktur.
Ancak, testlerde farklı bir durum söz konusu.

İçlerin Testi

Şimdi, InternalDirective'i test etmek istediğimizi hayal edelim ve ExternalModule ile MyComponent bunun bağımlılıklarıdır ve bunları sahte (mock) olanlarla değiştirmek istiyoruz.

InternalModule tüm bağımlılıklara sahip olduğu için, ilk bakışta, onu sahtelemek mantıklıdır:

TestBed.configureTestingModule({
imports: [
MockModule(InternalModule),
],
declarations: [
InternalDirective,
],
});

Ancak, bu beklediğimiz gibi olmayacak, çünkü InternalModule yalnızca MyComponent'i dışa aktarıyor ve dolayısıyla, test modülünde ExternalModule'e erişim yok.

Test modülündeki imports kısmına MockModule(ExternalModule) ekleyebiliriz, ancak, kod kötü hissettirmeye başlıyor çünkü ExternalModule zaten InternalDirective'nin ait olduğu modülde içe aktarılmış durumda olup, ekstra bir MockModule(ExternalModule) içe aktarımının yapılması yanlıştır.

Görünüşe göre, MockModule içe aktarımlarını ve tanımlarını dışa aktarıyorsa, bu durumu çözebilir.

Evet... bu, 9'dan önceki versiyonlarda böyleydi, ama o zaman başka bir sorun ortaya çıktı ve bu da dış yapılar (ihracatlar) ile ilgiliydi.
— Açıklayıcı Not

Dışların Testi

Şimdi, MyComponent'i test etmek istediğimizi hayal edelim.
Hikaye aynı, ExternalModule ve InternalDirective bunun bağımlılıklarıdır ve bunları sahte (mock) olanlarla değiştirmek istiyoruz.

InternalModule tüm bağımlılıklara sahip olduğu için, ilk bakışta, onu sahtelemek mantıklıdır:

TestBed.configureTestingModule({
imports: [
MockModule(InternalModule),
],
declarations: [
MyComponent,
],
});

Ayrıca, dışa aktarımları yapılmamış olan InternalDirective sorunu dışında başka bir sorun daha var.

Çünkü MockModule(InternalModule) MockComponent(MyComponent)'i dışa aktarıyor, bu nedenle artık test modülünde MyComponent'in iki tanımı var.
Sonunda, 2 modülün tanımlarıyla ilgili hata alacağız.

Bu, MyComponent için bağımlılıkları sahtelemek istediğimiz testlerde, InternalModule'ü kullanamayacağımız anlamına geliyor.

Çözüm

Eğer hızlı başlangıç dökümanını okuduysanız, bunu biliyorsunuzdur.
Bu, MockBuilder ya da ngMocks.guts kullanılarak başarılabilir.

Her ikisi de sorunu çözüyor, ancak farklı yollarla.

MockBuilder

MockBuilder(InternalDirective, InternalModule), InternalModule için yeni bir tanım oluşturur, burada InternalDirective dışa aktarılmıştır, böylece InternalDirective tekrar tüm bağımlılıklarına erişebilir ve testte InternalDirective'e erişimimiz olur:

@NgModule({
imports: [
MockModule(ExternalModule),
],
declarations: [
MockComponent(MyComponent),
InternalDirective,
],
exports: [
MockComponent(MyComponent),
InternalDirective,
],
})
class MockInternalModule {}

TestBed.configureTestingModule({
imports: [
MockInternalModule,
],
});
bilgi

MockBuilder ile, ihtiyaç duyduğumuzda dışa aktarma davranışını değiştirebiliriz, bu, export ve exportAll bayraklarıyla gerçekleştirilebilir.

ngMocks.guts

ngMocks.guts(InternalDirective, InternalModule), InternalModule'ün iç yapısını basitçe sahteleyerek, test modülünün tanımı şöyle görünür:

TestBed.configureTestingModule({
imports: [
MockModule(ExternalModule),
],
declarations: [
MockComponent(MyComponent),
InternalDirective,
],
});