Uygulamamın "yapıştırıcı" katmanı için birim testleri yazıyorum ve kullanıcının işlemi erken iptal etmesine izin veren eşzamansız yöntemler için deterministik testler oluşturmada zorluk yaşıyorum.Uzun süren ünite testinde orkestrasyon iptali
Özellikle, bazı zaman uyumsuz yöntemlerde, çağrının iptal edilmesine tepki veren ve tamamlanmadan önce nesnenin uygun durumda olmasını sağlayan bir kodumuz vardır. Bu kod yollarının testlerle karşılandığından emin olmak isterim. aşağıdaki gibi
Bu senaryoda, tipik bir zaman uyumsuz yöntemi örneklendiren Bazı C# sözde kodu:
public void FooAsync(CancellationToken token, Action<FooCompletedEventArgs> callback)
{
if (token.IsCancellationRequested) DoSomeCleanup0();
// Call the four helper methods, checking for cancellations in between each
Exception encounteredException;
try
{
MyDependency.DoExpensiveStuff1();
if (token.IsCancellationRequested) DoSomeCleanup1();
MyDependency.DoExpensiveStuff2();
if (token.IsCancellationRequested) DoSomeCleanup2();
MyDependency.DoExpensiveStuff3();
if (token.IsCancellationRequested) DoSomeCleanup3();
MyDependency.DoExpensiveStuff4();
if (token.IsCancellationRequested) DoSomeCleanup4();
}
catch (Exception e)
{
encounteredException = e;
}
if (!token.IsCancellationRequested)
{
var args = new FooCompletedEventArgs(a bunch of params);
callback(args);
}
}
I tutkal tabakası ile sarılır yatan MyDependency
işlemleri alay kadar ile gelip içerir olan çözelti ve her birini keyfi bir süre için uyumaya zorluyorlar. Daha sonra async yöntemini çağırıyorum ve birim sınamamıza async isteğini iptal etmeden önce birkaç milisaniye uyumaya anlatıyorum. (Örnek olarak Rhino dalga geçer kullanarak) böyle
şey: bir birim testinde Thread.Sleep kullanarak kusacak beni yapar olmasından Kenara
[TestMethod]
public void FooAsyncTest_CancelAfter2()
{
// arrange
var myDependency = MockRepository.GenerateStub<IMyDependency>();
// Set these stubs up to take a little bit of time each so we can orcestrate the cancels
myDependency.Stub(x => x.DoExpensiveStuff1()).WhenCalled(x => Thread.Sleep(100));
myDependency.Stub(x => x.DoExpensiveStuff2()).WhenCalled(x => Thread.Sleep(100));
myDependency.Stub(x => x.DoExpensiveStuff3()).WhenCalled(x => Thread.Sleep(100));
myDependency.Stub(x => x.DoExpensiveStuff4()).WhenCalled(x => Thread.Sleep(100));
// act
var target = new FooClass(myDependency);
CancellationTokenSource cts = new CancellationTokenSource();
bool wasCancelled = false;
target.FooAsync(
cts.Token,
args =>
{
wasCancelled = args.IsCancelled;
// Some other code to manipulate FooCompletedEventArgs
});
// sleep long enough for two operations to complete, then cancel
Thread.Sleep(250);
cts.Cancel();
// Some code to ensure the async call completes goes here
//assert
Assert.IsTrue(wasCancelled);
// Other assertions to validate state of target go here
}
, daha büyük bir sorun bazen böyle testler başarısız olmasıdır Eğer önemli bir yük altında olsaydı bizim yapı sunucusunda. Async çağrısı çok uzağa gider ve iptal çok geç olur.
Böyle uzun çalışma işlemleri için daha güvenilir bir şekilde birim testi iptal mantığı sağlayan herhangi biri var mı? Herhangi bir fikir takdir edilecektir.
Bu son derece umut verici görünüyor. Bu öğleden sonra deneyeceğim ve geri bildireceğim. –
Güzel çalıştı. Yardım ettiğin için teşekkür ederim! –