Angular 2 Testi - Eşzamansız işlev çağrısı - ne zaman kullanılır


89

Angular 2'de test yaparken TestBed'deki zaman uyumsuz işlevini ne zaman kullanırsınız?

Bunu ne zaman kullanıyorsun?

 beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [MyModule],
            schemas: [NO_ERRORS_SCHEMA],
        });
    });

Ve bunu ne zaman kullanacaksın?

beforeEach(async(() => {
    TestBed.configureTestingModule({
        declarations: [MyModule],
        schemas: [NO_ERRORS_SCHEMA],
    });
}));

Biri beni bu konuda aydınlatabilir mi?

Yanıtlar:


97

asyncasynctüm görevlerini bitirene kadar sonraki testin başlamasına izin vermeyecektir . Ne asyncyapar geri aramayı, tüm eşzamansız görevlerin (örneğin setTimeout) izlendiği bir Bölgeye kaydırmaktır . Eşzamansız tüm görevler tamamlandığında, asynctamamlanır.

Jasmine ile Angular dışında daha önce çalıştıysanız done, geri aramanın geçirildiğini görmüş olabilirsiniz.

it('..', function(done) {
  someAsyncAction().then(() => {
    expect(something).toBe(something);
    done();
  });
});

Burada, burası Jasmine, Jasmine'e bu testin biz arayana kadar tamamlamayı ertelemesi gerektiğini söylediğimiz yer done(). Biz aramadıysak done()ve yerine şunu yaptıysak:

it('..', function() {
  someAsyncAction().then(() => {
    expect(something).toBe(something);
  });
});

Test, beklentiden önce bile tamamlanır, çünkü söz daha sonra çözülür , senkron görevleri yürütme test bittikten .

Angular ile (Jasmine ortamında), Angular, kullandığımızda aslında doneperde arkasını arayacaktır async. Bölgedeki tüm asenkron görevleri takip edecek ve hepsi bittiğinde donesahne arkasına çağrılacak.

TestBedKonfigürasyonla ilgili özel durumunuzda , bunu genellikle istediğiniz zaman kullanırsınız compileComponents. Başka türlü adlandırmak zorunda kalacağım bir duruma nadiren rastlarım

beforeEach(async(() => {
   TestBed.configureTestingModule({
     declarations: [MyModule],
     schemas: [NO_ERRORS_SCHEMA],
   })
   .compileComponent().then(() => {
      fixture = TestBed.createComponent(TestComponent);
   });
}));

Kullanan bir bileşeni test ederken templateUrl(web paketi kullanmıyorsanız), Angular'ın şablonu almak için bir XHR isteği yapması gerekir, böylece bileşenin derlemesi eşzamansız olacaktır. Bu yüzden teste devam etmeden önce çözülmesini beklemeliyiz.


1
Harika cevap @peeskillet. Sadece anladığımdan emin olmak için: Satır içi bir şablonunuz asyncolduğunda gerekli değildir. Kullanırken templateUrl, öyle. Ancak, dahil etmek async, bir satır içi şablon bileşenini "bozmaz". Bir kişinin asyncher test için varsayılan olarak kullanılabileceğini söylemenin güvenli olduğunu düşünüyor musunuz ?
vince

2
@vincecampanale templateUrl yalnızca beforeEach içindeki yapılandırma sırasında önemlidir. Bu durumda aramanız gerekir compileComponents. İstediğiniz asyncbuysa, her testte kullanmakla hiçbir ilgisi yoktur . Güvende olmakla ilgili olarak (ne zaman aramanız gerekir compileComponents), bkz. Derleme Bileşenlerini ne zaman çağırmalıyım
Paul Samsotha

2
@vincecampanale Testten önce çağrılmasını istediğiniz her zaman bu değildir . Bazen bir miktar başlatma yaptıktan sonra onu aramak isteyebilirsiniz. Onu aramanın gerçekte ne işe yaradığını anlamanız gerekir. Yine de çoğu zaman sorun olmaz. Ama şahsen, bu kararı vermeyi kendilerine vermelerinden hoşlanmıyorum. Ama birçok insanın problemi aramayı unuttukları yerde karşılaştığını görüyorum ve neden bazı şeylerin işe yaramadığını merak ediyorlar. Bu yüzden belki de aramayı oluşturmaları daha iyidir. Konum tartışmalı olabilir, ama en azından öyle diyorlar
Paul Samsotha

2
@vincecampanale Genel olarak görünümün (yeniden) oluşturulmasını istediğinizde onu çağırmanız gerekir. Örneğin, Bileşen Oluştur -> işleme görünümü. Ancak, önce Bileşen Oluştur -> oluşturma görünümü için kullanılan bileşendeki değeri değiştir -> oluşturma görünümü gibi bir şeyi başlatmak istiyorsanız. Demek istediğim bu, belki de önce bir şeyi başlatmak istiyorsunuz
Paul Samsotha

1
Oh ve bir şey daha. Onu ilk çağırdığınızda ngOnInit, bileşenin ne zaman çağrıldığıdır. Bazen test yaparken bu önemlidir
Paul Samsotha

26

Testinizde zaman uyumsuz bir çağrı yaptığınızda, asenkron çağrı tamamlanmadan önce gerçek test işlevi tamamlanır. Çağrı tamamlandığında bir durumu doğrulamanız gerektiğinde (ki bu genellikle durum böyledir), o zaman test çerçevesi hala eşzamansız çalışma devam ederken testi tamamlandı olarak bildirir.

Kullanarak async(...)test çerçevesine, testi tamamlanmış olarak değerlendirmeden önce iade vaadi veya gözlemlenebilir olanın tamamlanmasını beklemesini söyleyin.

it('should show quote after getQuote promise (async)', async(() => {
  fixture.detectChanges();

  fixture.whenStable().then(() => { // wait for async getQuote
    fixture.detectChanges();        // update view with quote
    expect(el.textContent).toBe(testQuote);
  });
}));

Aktarılan kod , test işlevi tamamlandıktan sonrathen(...) çalıştırılacaktır . İle size tamamlanmadan olarak testini tedavisinde önce tamamlanmasını vaatler ve gözlenebilirlerin beklemek gerektiğini test çerçevesi farkında olun.async()

Ayrıca bakınız

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.