【发布时间】:2010-10-12 22:39:50
【问题描述】:
我正在尝试为将视图模型作为其唯一参数的 ASP.NET MVC 2 发布操作编写单元测试。视图模型装饰有验证属性,例如 [Required]。我想测试两个场景。第一种情况是传入一组有效数据(即所有必需的属性都有值)并返回到列表页面的重定向。第二种情况涉及传入无效数据(例如,当一个或多个必需属性未设置时)。在这种情况下,将返回相同的视图并显示错误消息。
动作签名如下:
[HttpPost]
public virtual ActionResult Create(NewsViewModel model)
NewsViewModel 类如下:
public class NewsViewModel
{
public Guid Id { get; set; }
public DateTime? PublishStartDate { get; set; }
public DateTime? PublishEndDate { get; set; }
[Required]
[StringLength(1000,
ErrorMessage = "Title must be less than 1000 characters.")]
[HtmlProperties(Size = 100, MaxLength = 1000)]
public string Title { get; set; }
[Required]
public string Content { get; set; }
[DisplayName("Published")]
[Required]
public bool IsPublished { get; set; }
[Required]
public string Category { get; set; }
public DateTime PublishedDateTime { get; set; }
}
我对第一个场景的单元测试如下:
[Test]
public void Create_Post()
{
DateTime now = DateTime.Now;
Guid id = Guid.NewGuid();
// Act
NewsViewModel viewModel = new NewsViewModel()
{
Id = id,
Title = "Test News",
Content = "this is the content",
Category = "General",
PublishedDateTime = now,
PublishEndDate = now.Add(new TimeSpan(1, 0, 0)),
PublishStartDate = now.Subtract(new TimeSpan(1, 0, 0))
};
ActionResult result = _controller.Create(viewModel);
// Assert
result.AssertActionRedirect();
}
控制器是使用 MvcContrib TestControllerBuilder 在测试设置中创建的:
private IWebDataService _webDataServiceFake;
private TestControllerBuilder _builder;
private PortalNewsController _controller;
[SetUp]
public void Setup()
{
_webDataServiceFake = new WebDataService(new EntityDataServiceFake());
_controller = new PortalNewsController(_webDataServiceFake);
_builder = new TestControllerBuilder();
_builder.InitializeController(_controller);
}
此测试按预期通过,返回一个重定向到列表页面的操作。我想创建一个它的克隆,其中许多必需的属性为空或空。在这种情况下,测试应该返回视图渲染操作而不是重定向。我的尝试如下:
[Test]
public void Create_PostInvalid()
{
DateTime now = DateTime.Now;
Guid id = Guid.NewGuid();
// Act
NewsViewModel viewModel = new NewsViewModel()
{
Id = id,
Title = null,
PublishedDateTime = now,
PublishEndDate = now.Add(new TimeSpan(1, 0, 0)),
PublishStartDate = now.Subtract(new TimeSpan(1, 0, 0)),
Content = null,
Category = ""
};
ActionResult result = _controller.Create(viewModel);
// Assert
result.AssertViewRendered();
}
即使我为 Content 属性传递了一个 null 并为 Category 属性传递了一个空字符串,但单元测试还是失败了,因为当我调用 Create 操作时,ViewState 表明模型是有效的。
我假设我调用操作时没有调用验证代码,因为我直接调用它我并不感到惊讶。那么,在调用 action 方法之前,如何编写一个单元测试来在视图模型上执行所有预期的验证呢?
我正在使用:ASP.NET MVC2、NUnit 2.5.7 和 MvcContrib 2.0.96.0。
感谢您的帮助。 格伦。
【问题讨论】:
-
阅读 Brad 提供的链接后,我发现诀窍是添加“_controller.ModelState.AddModelError("*", "Invalid model state");"就在调用 Create 操作之前。这向控制器表明发生了验证错误,因此根据需要通过代码采用无效路径。谢谢布拉德。
标签: c# asp.net asp.net-mvc-2 nunit mvccontrib