[英]Unit test MVC controller with Microsoft Fakes
我有一個非常基本的MVC控制器,但是我不知道如何為我的控制器動作設置偽造品。 我是新來的,所以任何幫助都會很棒。 我使用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");
}
終於讓它工作了。 成功版本:
[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");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.