2010-06-03 18 views
10

Bazı MVC denetleyicilerinin yeniden denetleyicileri yeniden yazılmasını düşünüyorum. Bu denetleyiciler için çalışma birimi testlerim var, ancak bunları bir async denetleyici ortamında nasıl koruyacağımı anlamaya çalışıyorum.MVC2 AsyncControllers için bina birimi testleri

Örneğin, şu anda böyle bir eylem vardır:

public ContentResult Transaction() 
{ 
    do stuff... 
    return Content("result"); 
} 

ve benim birim test temelde benzer:

var result = controller.Transaction(); 
Assert.AreEqual("result", result.Content); 

Tamam, bu çok kolay.

Ama kontrolör değişiklikler bu gibi görünmek zaman:

public void TransactionAsync() 
{ 
    do stuff... 
    AsyncManager.Parameters["result"] = "result"; 
} 

public ContentResult TransactionCompleted(string result) 
{ 
    return Content(result); 
} 

nasıl birim testleri sence inşa edilmelidir? Elbette, test yönteminizde async başlatıcı yöntemini çağırabilirsiniz, ancak dönüş değerine nasıl ulaşırsınız? Google'da bu konuda bir şey görmedim

... herhangi fikirler için

teşekkürler.

cevap

18

Tüm uyumsuz kodlarda olduğu gibi, birim sınamasının, iş parçacığı sinyallemesinin farkında olması gerekir.

public class MyAsyncController : Controller 
{ 
    public void TransactionAsync() 
    { 
    AsyncManager.Parameters["result"] = "result"; 
    } 

    public ContentResult TransactionCompleted(string result) 
    { 
    return Content(result); 
    } 
} 

[TestFixture] 
public class MyAsyncControllerTests 
{ 
    #region Fields 
    private AutoResetEvent trigger; 
    private MyAsyncController controller; 
    #endregion 

    #region Tests 
    [Test] 
    public void TestTransactionAsync() 
    { 
    controller = new MyAsyncController(); 
    trigger = new AutoResetEvent(false); 

    // When the async manager has finished processing an async operation, trigger our AutoResetEvent to proceed. 
    controller.AsyncManager.Finished += (sender, ev) => trigger.Set(); 

    controller.TransactionAsync(); 
    trigger.WaitOne() 

    // Continue with asserts 
    } 
    #endregion 
} 

Umut yardımcı olur :)

+0

Kodda bunu denemek için sabırsızlanıyorum, ancak muhteşem görünüyor. Onu çalıştırdıktan sonra cevaplandı olarak işaretler. Çok teşekkürler! – ChrisW

1

Ben birim test kolaylaştıran kısa AsyncController uzatma yöntemi yazdık: .NET bir zaman uyumsuz işlem tamamlanıncaya kadar deney iplik engelleyebilirsiniz AutoResetEvent adında bir türünü içerir bit.

static class AsyncControllerExtensions 
{ 
    public static void ExecuteAsync(this AsyncController asyncController, Action actionAsync, Action actionCompleted) 
    { 
     var trigger = new AutoResetEvent(false); 
     asyncController.AsyncManager.Finished += (sender, ev) => 
     { 
      actionCompleted(); 
      trigger.Set(); 
     }; 
     actionAsync(); 
     trigger.WaitOne(); 
    } 
} 

Bu şekilde biz sadece 'gürültü' diş gizleyebilirsiniz: ne hakkında bir blog yazısı yazdım daha fazla bilgi edinmek istiyorsanız

public class SampleAsyncController : AsyncController 
{ 
    public void SquareOfAsync(int number) 
    { 
     AsyncManager.OutstandingOperations.Increment(); 

     // here goes asynchronous operation 
     new Thread(() => 
     { 
      Thread.Sleep(100); 

      // do some async long operation like ... 
      // calculate square number 
      AsyncManager.Parameters["result"] = number * number; 

      // decrementing OutstandingOperations to value 0 
      // will execute Finished EventHandler on AsyncManager 
      AsyncManager.OutstandingOperations.Decrement(); 
     }).Start(); 
    } 

    public JsonResult SquareOfCompleted(int result) 
    { 
     return Json(result); 
    } 
} 

[TestFixture] 
public class SampleAsyncControllerTests 
{ 
    [Test] 
    public void When_calling_square_of_it_should_return_square_number_of_input() 
    { 
     var controller = new SampleAsyncController(); 
     var result = new JsonResult(); 
     const int number = 5; 

     controller.ExecuteAsync(() => controller.SquareOfAsync(number), 
           () => result = controller.SquareOfCompleted((int)controller.AsyncManager.Parameters["result"])); 

     Assert.AreEqual((int)(result.Data), number * number); 
    } 
} 

nasıl Unit test ASP.NET MVC 3 asynchronous controllers using Machine.Specifications Yoksa bu kontrol etmek istiyorsanız kod, bir github