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 はデフォルトで true になると思います。

これをテストするにはどうすればよいですか?単体テストでモデルの検証をトリガーするにはどうすればよいですか?

4

4 に答える 4

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 に答える
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;
    }
}

2 つ目は、単体テストです。特定のプロパティに対して特定のエラー メッセージが表示されると予想されるテストを作成します。この例では、null 値を指定し、プロパティ "Name" に対して "Name is Empty" というエラー メッセージが表示されることを期待しています。

    [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 に答える
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 に答える