I have written my first unit tests for an ASP.NET MVC web application. All works fine and it is giving me valuable information, but I can't test errors in the view model. The ModelState.IsValid is always true, even when some values are not filled in (empty string or null).
I have read already that the model validation happens when the posted data is mapped to the model and you need to write some code to do the model verification yourself:
I have tried the three examples provided in the linked webpages, but it seems not to work for me.
Some code:
My viewmodel
...
[Required(ErrorMessageResourceName = "ErrorFirstName", ErrorMessageResourceType = typeof(Mui))]
[MaxLength(50)]
[Display(Name = "Firstname", ResourceType = typeof(Mui))]
public string FirstName { get; set; }
...
The controller
...
 [HttpPost]
    public ActionResult Index(POSViewModel model)
    {
        Contract contract = contractService.GetContract(model.ContractGuid.Value);
        if (!contract.IsDirectDebit.ToSafe())
        {
            ModelState.Remove("BankName");
            ModelState.Remove("BankAddress");
            ModelState.Remove("BankZip");
            ModelState.Remove("BankCity");
            ModelState.Remove("AccountNr");
        }
        if (ModelState.IsValid)
        {
            ...
            contractValidationService.Create(contractValidation);
            unitOfWork.SaveChanges();
            return RedirectToAction("index","thanks");
        }
        else
        {
            return Index(model.ContractGuid.ToString());
        }
    }
My unit test
  posViewModel.FirstName = null;
  posViewModel.LastName = "";
 ...
 var modelBinder = new ModelBindingContext()
        {
            ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => posViewModel, posViewModel.GetType()),
            ValueProvider = new NameValueCollectionValueProvider(new System.Collections.Specialized.NameValueCollection(), CultureInfo.InvariantCulture)
        };
        var binder = new DefaultModelBinder().BindModel(new ControllerContext(), modelBinder);
        posController.ModelState.Clear();
        posController.ModelState.Merge(modelBinder.ModelState);
        ActionResult result = posController.Index(posViewModel);
        //Assert
        mockContractValidationService.Verify(m => m.Create(It.IsAny<ContractValidation>()), Times.Never);
        Assert.IsInstanceOfType(result, typeof(ViewResult));
On the view, I'm using unobtrusive JavaScript validation, and it works.