2011-12-19 192 views
14

我的ASP.NET MVC应用程序中的一个控制器根据几个相当直接的规则预填充我的视图显示的表单数据。单元测试MVC控制器

在我的单元测试中,这似乎是一件好事。但是我能够看到验证正确数据的唯一方法就是放在表单中,就是从控制器中提取逻辑,看起来像一种不自然的方式。

有人可以建议方法来解决这个问题吗?

我发现的单元测试控制器的所有示例看起来都很平凡,比如验证它返回了预期的视图类型。我不确定我甚至看到了它的价值。

回答

21

您可以通过返回的对象强制转换为相应的类,而不是使用其基类(这是默认的返回)

例如,测试默认测试AccountController你会这样是这样的:

var controller = new AccountController(); 
var result = controller.LogOn() as ViewResult; 
var model = result.Model as LogOnModel; 

Assert.IsTrue(model.RememberMe); // assuming you "pre-populated" enabled the checkbox 

检查返回的对象填充正确的数据似乎并没有“不自然”对我来说,还是你的意思是不同的?

+1

啊...'result.Model'看起来有帮助。 – 2011-12-19 16:01:42

11

我同意测试返回的视图类型会有点毫无意义。但是,测试预期的“视图”与其正确的数据一起返回将是一个有效的测试用例IMO。

例如,这里是编辑控制器的单数编辑测试用例。请注意,这个例子正在使用Moq和Nunit,但除此之外它非常简单。

请注意,ViewResult将转换为预期的视图模型,然后对预期的联系进行断言。

测试:

[Test] 
public void Edit_Get_Should_Lookup_Contact_From_Repository_And_Return_Edit_View() 
{ 
    // arrange 
    var _repository = new Mock<IContactRepository>(); 

    var expectedContact = new Contact 
    { 
     First = "first", 
     Last = "last", 
     Email = "[email protected]" 
    }; 

    var mockContext = new Mock<ControllerContext>(); 
    _repository.Setup(x => x.GetById(It.IsAny<int>())).Returns(expectedContact); 

    var controller = new ContactController(_repository.Object) 
    { 
     ControllerContext = mockContext.Object 
    }; 

    // act 
    var result = controller.Edit(1) as ViewResult; 
    var resultData = (Contact)result.ViewData.Model; 

    // assert 
    Assert.AreEqual("Edit", result.ViewName); 
    Assert.AreEqual(expectedContact.First, resultData.First); 
    Assert.AreEqual(expectedContact.Last, resultData.Last); 
    Assert.AreEqual(expectedContact.Email, resultData.Email); 
} 

控制器:

[HttpGet] 
public ActionResult Edit(int id) 
{ 
    var contact = _repository.GetById(id); 

    return View("Edit", contact); 
}