3

我开始学习 MVC4 中的单元测试。

这是我的控制器。

public class AccountController : Controller
{
    public ActionResult Register(User user)
    {
        if (ModelState.IsValid)
        {
            return View("RegistrationSuccessful");                
        }
        return View("Register");
    }
}

这就是考验。

public class AccountControllerTests
{
    [TestMethod]
    public void invalid_registration_details_should_show_registration_form_again()
    {
        var controller = new AccountController();
        var user = new User();
        user.Name = null;
        var result = controller.Register(user) as ViewResult;
        Assert.AreEqual("Register", result.ViewName);
    }
}

这就是模型。

public class User
{
    [Required]
    public string Name { get; set; }
}

当我调用 controller.Register(user) 时,我认为模型绑定器不会出现,因为我自己实例化控制器而不是通过框架。所以我认为 ModelState.IsValid 默认为真。

我该如何测试这个?如何在单元测试中触发模型验证?

4

4 回答 4

2

由于控制器中除了检查 ModelState.IsValid==true 之外没有其他逻辑,我认为您可能只需要对模型进行单元测试。

首先,你的模型。我会将其更改为如下所示:

public class User : IValidatableObject
{
    public string Name { get; set; }
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // I personally add all my validation here instead of adding [Required] to specific properties, this helps me know all of my validation is in this one place and add other complex validations if needed
        // This code here determines if ModelState.IsValid 
        var retVal = new List<ValidationResult>();
        if (string.IsNullOrEmpty(this.Name))
        {
            retVal.Add(new ValidationResult("Name is Empty", new List<string> { "Name" }));
        }
        return retVal;
    }
}

二是单元测试。我会编写测试,我希望特定属性的特定错误消息。在此示例中,我给出了一个空值,并期待属性“名称”的错误消息“名称为空”:

    [TestMethod]
    public void NullOrEmptyName()
    {
        var model = new YourProject.Models.Account.User { Name= null };
        var validationContext = new ValidationContext(model);
        var validation = model.Validate(validationContext).ToList();
        Assert.AreEqual(validation.Count(x => x.ErrorMessage == "Name is empty" && x.MemberNames.Single() == "Name"), 1);
    }
于 2015-04-29T15:18:00.673 回答
2

您也可以通过以下方法来验证模型。在我的例子中,ProjectViewModel 是我的模型。在下面的场景中,我没有设置 Description 属性来验证验证是否有效。

[TestMethod]
[ExpectedException(typeof(ValidationException), "Please enter description.")]
public void Create_Project_Empty_Description()
{
    ProjectViewModel model = new ProjectViewModel
    {
        ProjectID = 3,
        Name = "Test Project",
        StartDate = DateTime.Now.Date,
        EndDate = DateTime.Now.AddMonths(-1),
        States = new List<ProjectStateViewModel> { new ProjectStateViewModel { StateName = "Pending" } }
    };

    ValidationContext contex = new ValidationContext(model);
    Validator.ValidateObject(model, contex);
}
于 2014-07-14T01:43:14.627 回答
0

我不确定是否可以触发模型验证,但我知道如何测试它。

试试这个代码:

    [TestClass]
    public class AccountControllerTests
    {
        [TestMethod]
        public void invalid_registration_details_should_show_registration_form_again()
        {
            // arrange
            var controller = new AccountController();
            controller.ViewData.ModelState.AddModelError("Key", "ErrorMessage");

            // act
            var result = controller.Register(new User()) as ViewResult;

            // assert
            Assert.AreEqual("Register", result.ViewName);
        }

        [TestMethod]
        public void valid_registration_details_should_show_registration_successful_page()
        {
            // arrange
            var controller = new AccountController();

            // act
            var result = controller.Register(new User()) as ViewResult;

            // assert
            Assert.AreEqual("RegistrationSuccessful", result.ViewName);
        }
    }
于 2013-08-14T18:18:12.437 回答
0

您可以通过从测试中调用以下命令来强制它验证您的模型来做到这一点。对于我的测试,我创建了一个TestHelper类,其中模拟了这个方法并添加ModelState.AddModelError()了特定条件。

TryValidateModel(model);// will do the task

可能您也需要为此模拟ControllerContext

于 2013-08-16T20:22:49.650 回答