2011-12-19 262 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); 
}