[英]Unit test MVC controller with Microsoft Fakes
I have a very basic MVC Controller but I can't figure out how to setup fakes for my Controller action. 我有一个非常基本的MVC控制器,但是我不知道如何为我的控制器动作设置伪造品。 I'm new with this so any help would be great.
我是新来的,所以任何帮助都会很棒。 I use EF 6.1, MVC 5.1 and .NET 4.5.1.
我使用EF 6.1,MVC 5.1和.NET 4.5.1。
Controller: 控制器:
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);
}
}
Model: 模型:
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; }
}
Test method: 测试方法:
[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");
}
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. 您还必须先验证对象,然后再将viewModel提交给乘员组方法。 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");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.