Finally got it to work. Succeed version:
[TestMethod]
public void CreateMemberSucceededTest()
{
using (ShimsContext.Create())
{
// Arrange
var mockSet = new StubDbSet<Member>();
ShimApplicationDbContext.Constructor = (t) => { };
ShimApplicationDbContext.AllInstances.MembersGet = (t) =>
{
return mockSet;
};
ShimDbContext.AllInstances.SaveChanges = (t) => { return 1; };
MemberController controller = new MemberController();
MemberCreateViewModel vm = new MemberCreateViewModel()
{
Addition = "A",
BirthDay = new DateTime(1995, 10, 14),
City = "Rotterdam",
Email = "test.user@fake.com",
FirstName = "Test",
HouseNumber = 4,
LastName = "Persoon",
MemberSince = new DateTime(2007, 10, 8),
MobileNumber = "1234567890",
PhoneNumber = "1234567890",
Street = "Staartmanslaan",
ZipCode = "3134kl"
};
// Act
Validate(controller, vm);
var result = controller.Create(vm) as RedirectToRouteResult;
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(result.RouteValues["action"], "Index");
}
}
You also have to validate the object before submitting the viewModel to your crewate methode. If you don't do that your modelstate is always valid.
private static void Validate(MemberController controller, object entityToValidate)
{
var valResults = TryValidate(entityToValidate);
SetErrorInModelState(valResults, controller);
}
internal static Collection<ValidationResult> TryValidate(object entityToValidate)
{
var result = new Collection<ValidationResult>();
Validator.TryValidateObject(entityToValidate, new ValidationContext(entityToValidate, null, null), result, true);
return result;
}
internal static void SetErrorInModelState(Collection<ValidationResult> validationErrors, Controller controller)
{
foreach (var validationError in validationErrors)
{
controller.ModelState.AddModelError(validationError.MemberNames.First(), validationError.ErrorMessage);
}
}
A version where in example the email is invalid: First a generic method for validating the method so we can use it for separate properties in the model:
private static void CreateMemberValidationTest(MemberCreateViewModel vm, string propertyThatFails)
{
using (ShimsContext.Create())
{
// Arrange
var mockSet = new StubDbSet<Member>();
ShimApplicationDbContext.Constructor = (t) => { };
ShimApplicationDbContext.AllInstances.MembersGet = (t) =>
{
return mockSet;
};
ShimDbContext.AllInstances.SaveChanges = (t) => { return 1; };
MemberController controller = new MemberController();
// Act
Validate(controller, vm);
var result = controller.Create(vm) as ViewResult;
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(result.ViewData.ModelState.Count, 1);
Assert.AreEqual(result.ViewData.ModelState.Keys.First(), propertyThatFails);
}
}
And then the test that calls the method:
[TestMethod]
public void CreateMemberNoEmailTest()
{
var vm = new MemberCreateViewModel()
{
Addition = "A",
BirthDay = new DateTime(1995, 10, 14),
City = "Rotterdam",
Email = null,
FirstName = "Test",
HouseNumber = 4,
LastName = "Persoon",
MemberSince = new DateTime(2007, 10, 8),
MobileNumber = "1234567890",
PhoneNumber = "1234567890",
Street = "Staartmanslaan",
ZipCode = "3134kl"
};
CreateMemberValidationTest(vm, "Email");
}