2014-07-18 29 views
5

Vuruldum asla beklenen Task<T> başvuran bir satırda bir async yöntemi ing await sonra benim kesme noktası şaşırdım:Birim testinde bekledikten sonra bir kesme noktası nasıl kullanılır?

[Test] 
    public async void GetSomethingTest() 
    { 
     var service = SimpleIoc.Default.GetInstance<IService>(); 
     var result = await service.TryGetSomethingAsync(20); 
     Assert.IsTrue(result.IsSuccess); 
     Assert.IsNotNull(result.ReturnValue); 
    } 

ilk Assert satırda kesme noktası koymak isabet asla fakat test geçer.

Beklerken ne zaman kırılırım?

GÜNCELLEME: Ben test çerçevesi, ben NUnit 2.6.3 kullanıyorum deney metodunun çağırmayı ing await değildir ve bu async destek iddia çünkü sanırım ancak o ben gibi bir await sonra kırma yapılıp yapılmayacağı yapmaya çalışıyorum, emin değilim ...

+1

Test yönteminizi async void konumundan async konumuna getirin Görev – Neel

+0

@Neel bu yardımcı olmadı :( – markmnl

+1

Hata ayıklama birimiyle ilgili her tür sorunla karşılaştım. İstediğiniz şekilde çalışmazsa, testinizi kopyalayın ConsoleApplication için ve orada hata ayıklayın.Bu çok daha az sorun var. – nvoigt

cevap

10

Sorun, yönteminizin async void olmasıdır. Bu, ateş-ve-unut semantik var. senin yöntem async ile ne yaptığını Kavramsal olarak

- await kullanımı şu şekildedir:
[Test] 
public void GetSomethingTest() 
{ 
    var service = SimpleIoc.Default.GetInstance<IService>(); 
    service.TryGetSomethingAsync(20).ContinueWith(t => 
    { 
     var result = t.Result; 
     Assert.IsTrue(result.IsSuccess); 
     Assert.IsNotNull(result.ReturnValue); 
    }); 
} 

Şimdi sorunun ne açık olmalıdır. Test yönteminiz, TryGetSomethingAsync öğesinin Task değerini döndürür. Yani test hemen biter. Hiçbir istisna atılmadığından, bu bir başarıdır.

test çerçevesi Task -returning testleri destekliyorsa, sadece Task yerine void olan dönüş türü değiştirerek istediğini yapmak için testini çözebilirsiniz.

[Test] 
public async Task GetSomethingTest() 
{ 
    var service = SimpleIoc.Default.GetInstance<IService>(); 
    var result = await service.TryGetSomethingAsync(20); 
    Assert.IsTrue(result.IsSuccess); 
    Assert.IsNotNull(result.ReturnValue); 
} 

Bu, kavramsal olarak aşağıdakilere çeviri yapar. Test çerçeve şimdi beklemek böylece Task devamı tüm testin kod testi bitmiş kabul edilir önce çalıştırmak için zamanının olmasını sağlayarak, döndürülür nasıl

[Test] 
public Task GetSomethingTest() 
{ 
    var service = SimpleIoc.Default.GetInstance<IService>(); 
    return service.TryGetSomethingAsync(20).ContinueWith(t => 
    { 
     var result = t.Result; 
     Assert.IsTrue(result.IsSuccess); 
     Assert.IsNotNull(result.ReturnValue); 
    }); 
} 

dikkat edin.

(Teknik olarak bir çerçeve de async void durumda çalışmak için yapılmış olabilir, ama bence bu iyi bir özellik olacaktır herhangi bir nedenle neden bilmiyorum, bu yüzden en çok dokunmayın bekliyoruz.)

Test çerçeveniz Görev döndüren testleri desteklemiyorsa, testinizi await yerine .Result kullanarak düzeltebilirsiniz. TryGetSomethingAsync tarafından döndürülen Task tamamlanana kadar

[Test] 
public void GetSomethingTest() 
{ 
    var service = SimpleIoc.Default.GetInstance<IService>(); 
    var result = service.TryGetSomethingAsync(20).Result; 
    Assert.IsTrue(result.IsSuccess); 
    Assert.IsNotNull(result.ReturnValue); 
} 

Bu sadece geçerli iş parçacığı engeller.

+0

MSTest'e geçiş yapmak ve 'Görev 'i tekrar döndürmek benim sorunumu çözdü, fakat ayrıntılı cevap sayesinde, diğerlerine yardımcı olacağından eminim! – markmnl

İlgili konular