我有一个非常基本的MVC控制器,但我无法弄清楚如何为我的Controller动作设置假动作。我是新手,所以任何帮助都会很棒。我使用EF 6.1,MVC 5.1和.NET 4.5.1。
控制器:
public class MemberController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,FirstName,LastName,BirthDay,MemberSince,Street,HouseNumber,Addition,ZipCode,City")] MemberCreateViewModel memberCreate)
{
if (ModelState.IsValid)
{
Mapper.CreateMap<MemberCreateViewModel, Member>();
var member = Mapper.Map<Member>(memberCreate);
db.Members.Add(member);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(memberCreate);
}
}
型号:
public class MemberCreateViewModel
{
[Display(Name = "Voornaam")]
[Required]
[StringLength(50)]
public string FirstName { get; set; }
[Display(Name = "Achternaam")]
[Required]
[StringLength(50)]
public string LastName { get; set; }
[Display(Name = "Geboortedatum")]
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime BirthDay { get; set; }
[Display(Name = "Lid sinds")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime MemberSince { get; set; }
[Display(Name = "Straat")]
[Required]
[StringLength(100)]
public string Street { get; set; }
[Display(Name = "Huisnummer", ShortName = "Huisnr")]
[Required]
[Range(1, 5000)]
public int HouseNumber { get; set; }
[Display(Name = "Toevoeging")]
public string Addition { get; set; }
[Display(Name = "Postcode")]
[Required]
[StringLength(6, MinimumLength = 6)]
public string ZipCode { get; set; }
[Display(Name = "Plaats")]
[Required]
[StringLength(40)]
public string City { get; set; }
[Display(Name = "Telefoonnummer", ShortName = "Telnr")]
[StringLength(10, MinimumLength = 10)]
public string PhoneNumber { get; set; }
[Display(Name = "Mobiel")]
[StringLength(10, MinimumLength = 10)]
public string MobileNumber { get; set; }
[Display(Name = "E-mail")]
[Required]
[EmailAddress]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
}
测试方法:
[TestMethod]
public void CreateSave()
{
var mockSet = new StubDbSet<Member>();
var mockContext = new StubApplicationDbContext()
{
//Members = () =>
// {
// return new StubDbSet<Member>();
// }
};
// Arrange
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
ViewResult result = controller.Create(vm) as ViewResult;
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(result.ViewName, "Index");
}
答案 0 :(得分:1)
终于开始工作了。成功版:
[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");
}
}
在将viewModel提交给您的船员方法之前,您还必须验证该对象。如果你不这样做,你的模型状态总是有效的。
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);
}
}
例如电子邮件无效的版本: 首先是验证方法的通用方法,以便我们可以将它用于模型中的单独属性:
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);
}
}
然后调用方法的测试:
[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");
}