2010-06-03 15 views
10

के लिए बिल्डिंग यूनिट परीक्षण मैं अपने कुछ एमवीसी नियंत्रकों को एसिंक नियंत्रकों के रूप में फिर से लिखने पर विचार कर रहा हूं। मेरे पास इन नियंत्रकों के लिए यूनिट परीक्षण कार्यरत हैं, लेकिन मैं समझने की कोशिश कर रहा हूं कि उन्हें एसिंक नियंत्रक वातावरण में कैसे बनाए रखा जाए।एमवीसी 2 AsyncControllers

उदाहरण के लिए, वर्तमान में मैं इस तरह एक कार्रवाई है:

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

और मेरी इकाई परीक्षण मूल रूप से दिखाई देता है:

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

ठीक है, वह पर्याप्त आसान है।

लेकिन जब अपने नियंत्रक परिवर्तन इस तरह देखने के लिए:

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

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

आप अपनी इकाई परीक्षण कैसे लगता है बनाया जाना चाहिए? आप निश्चित रूप से अपनी परीक्षण विधि में एसिंक प्रारंभकर्ता विधि का आह्वान कर सकते हैं, लेकिन आप वापसी मूल्य पर कैसे प्राप्त करते हैं?

मैं गूगल पर इस बारे में कुछ भी नहीं देखा है ...

किसी भी विचार के लिए धन्यवाद।

उत्तर

18

किसी भी एसिंक कोड के साथ, यूनिट परीक्षण को थ्रेड सिग्नलिंग के बारे में पता होना चाहिए।

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 
} 

आशा में मदद करता है :)

+0

पर कोड कोड में कोशिश करने के लिए मैं इंतजार नहीं कर सकता, लेकिन यह शानदार लग रहा है। इसे चलाने के बाद उत्तर के रूप में चिह्नित किया जाएगा। बहुत बहुत धन्यवाद! – ChrisW

1

मैं कम AsyncController विस्तार विधि है कि यूनिट एक परीक्षण को सरल लिखा है: .NET एक प्रकार AutoResetEvent कहा जाता है जो परीक्षण धागा जब तक एक async आपरेशन पूरा हो चुका है ब्लॉक कर सकते हैं शामिल बिट।

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(); 
    } 
} 

इस तरह हम बस 'शोर' सूत्रण छिपा सकते हैं:

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); 
    } 
} 

आप को पता है और मैं के बारे में एक ब्लॉग पोस्ट में लिखा है चाहते हैं कैसे Unit test ASP.NET MVC 3 asynchronous controllers using Machine.Specifications या आप इस जाँच करना चाहते हैं कोड github

संबंधित मुद्दे