Building unit tests for MVC2 AsyncControllers

后端 未结 2 830
无人及你
无人及你 2021-02-20 16:24

I\'m considering re-rewriting some of my MVC controllers to be async controllers. I have working unit tests for these controllers, but I\'m trying to understand how to maintain

2条回答
  •  感情败类
    2021-02-20 16:56

    I've written short AsyncController extension method that simplifies unit testing a 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();
        }
    }
    

    That way we can simply hide threading 'noise':

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

    If you want to know more I've written a blog post about how to Unit test ASP.NET MVC 3 asynchronous controllers using Machine.Specifications Or if you want to check this code it's on a github

提交回复
热议问题