如何单元测试具有Task.Run(())的Controller方法

时间:2017-07-27 16:58:14

标签: asp.net-mvc nunit

当控制器方法具有Task.Run()

时,需要知道如何编写Nunit测试用例

例如,查看下面的代码

 public class DataProcessController : Controller
    {        

        public ActionResult Index(DataProcess model)
        {
            try
            {
                Task task = Task.Run(() =>
                {
                    try
                    {
                        Database.Insert(model);
                    }
                    catch(Exception ex)
                    {
                        Database.Log(ex);
                    }
             });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("Not able to process the data",string.Empty);
                return this.View(model);
            }
            return RedirectToAction("Index");

        }
    }

*************************************************

 public class DataProcessControllerTest
    {
        [Test]
        public void Index()
        {
            DataProcessController objController = new DataProcessController();
            DataProcess process = new DataProcess() { ProcessId = 501, ProcessName = "MorningBatch" };
            var result = objController.Index(process);
            Assert.IsNotNull(result);
        }
    }

***********************************

当我们运行上面的测试方法时,它没有命中Task中的Database.Insert(model)行。我们需要测试是否插入了记录...

请帮助如何编写测试用例,它应该触及Controller方法中的所有代码行。

请帮忙。

1 个答案:

答案 0 :(得分:0)

首先,您需要将该操作重构为异步。根据示例中的代码,Database似乎也是static。这也使得测试变得困难。那个(Database)应该被抽象出来并明确注入控制器。

public class DataProcessController : Controller {
    private readonly IDatabase Database;

    public DataProcessController(IDatabase Database) {
        this.Database = Database;
    }

    public async Task<ActionResult> Index(DataProcess model) {
        try {
            await Task.Run(() => Database.Insert(model));                
        } catch(Exception ex) {
            Database.Log(ex);
            ModelState.AddModelError("Not able to process the data",string.Empty);
            return this.View(model);
        }
        return RedirectToAction("Index");
    }
}

这将为可维护性提供更大的灵活性,包括单元测试,

public class DataProcessControllerTest {
    [Test]
    public async Task Index() {
        //Arrange
        var process = new DataProcess() { ProcessId = 501, ProcessName = "MorningBatch" };
        //mock database
        var dbMock = new Mock<IDatabase>();            
        //inject mocked database into controller (SUT)
        var objController = new DataProcessController(dbMock.Object);

        //Act 
        var result = await objController.Index(process);

        //Assert 
        Assert.IsNotNull(result);
        //verify that the Insert method was called with the provided model
        dbMock.Verify(_ => _.Insert(process), Times.Once());
    }
}