Rob*_*ker 20 asp.net-mvc unit-testing
我有一个控制器,它在一个实体上实现一个简单的Add操作,并重定向到Details页面:
[HttpPost]
public ActionResult Add(Thing thing)
{
// ... do validation, db stuff ...
return this.RedirectToAction<c => c.Details(thing.Id));
}
Run Code Online (Sandbox Code Playgroud)
这很好用(使用MvcContrib程序集中的RedirectToAction).
当我单元测试这个方法时,我想访问从Details操作返回的ViewData(所以我可以获取新插入的东西的主键并证明它现在在数据库中).
测试有:
var result = controller.Add(thing);
Run Code Online (Sandbox Code Playgroud)
但这里的结果是类型:( System.Web.Mvc.RedirectToRouteResult这是一个System.Web.Mvc.ActionResult).它还没有执行Details方法.
我试过调用ExecuteResult返回的对象传递一个模拟,ControllerContext但框架不满意模拟对象中缺乏细节.
我可以尝试填写详细信息等,但是然后我的测试代码比我正在测试的代码更长,我觉得我需要进行单元测试的单元测试!
我错过了测试哲学中的一些东西吗?当我无法进入返回状态时,如何测试此操作?
Art*_*old 31
我现在正在使用MVC2 RC2,而rmacfie的答案对我来说并不是很有效,但确实让我走上正轨.
无论是对还是错,我设法在我的测试中做到了这一点:
var actionResult = (RedirectToRouteResult)logonController.ForgotUsername(model);
actionResult.RouteValues["action"].should_be_equal_to("Index");
actionResult.RouteValues["controller"].should_be_equal_to("Logon");
Run Code Online (Sandbox Code Playgroud)
不确定这是否会对某人有所帮助,但可能会为您节省10分钟.
Cha*_*let 12
MVC Contrib TestHelper非常适合测试大多数ActionResult
你可以在这里找到它:http: //mvccontrib.codeplex.com/wikipage?title = TestHelper
以下是语法示例:
var controller = new TestController();
controller.Add(thing)
.AssertActionRedirect()
.ToAction<TestController>(x => x.Index());
Run Code Online (Sandbox Code Playgroud)
要测试数据是否已成功保存,您应该直接询问您的数据库,我不知道您是否正在使用ORM或其他东西,但是您应该做一些事情来获取数据库中最后一个已插入的项目,然后比较使用您为Add ActionResult提供的值,看看是否正常.
我不认为测试您的Details ActionResult以查看您的数据是否持久化是正确的方法.那不是单元测试,更像是功能测试.
但是,您还应该对您的Details方法进行单元测试,以确保您的viewdata对象充满了来自您的数据库的正确数据.
你似乎为单元测试做了太多的事情.验证和数据访问通常由您从控制器操作调用的服务完成.你嘲笑那些服务,只测试他们被正确调用.
像这样的东西(使用Rhino.Mocks和NUnit的近似语法):
[Test]
public void Add_SavesThingToDB()
{
var dbMock = MockRepository.GenerateMock<DBService>();
dbMock.Expect(x => x.Save(thing)).Repeat.Once();
var controller = new MyController(dbMock);
controller.Add(new Thing());
dbMock.VerifyAllExpectations();
}
[Test]
public void Add_RedirectsAfterSave()
{
var dbMock = MockRepository.GenerateMock<DBService>();
var controller = new MyController(dbMock);
var result = (RedirectToRouteResult)controller.Add(new Thing());
Assert.That(result.Url, Is.EqualTo("/mynew/url"));
}
Run Code Online (Sandbox Code Playgroud)
我有一个静态帮助方法来测试重定向.
public static class UnitTestHelpers
{
public static void ShouldEqual<T>(this T actualValue, T expectedValue)
{
Assert.AreEqual(expectedValue, actualValue);
}
public static void ShouldBeRedirectionTo(this ActionResult actionResult, object expectedRouteValues)
{
RouteValueDictionary actualValues = ((RedirectToRouteResult)actionResult).RouteValues;
var expectedValues = new RouteValueDictionary(expectedRouteValues);
foreach (string key in expectedValues.Keys)
{
Assert.AreEqual(expectedValues[key], actualValues[key]);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后创建重定向测试非常容易.
[Test]
public void ResirectionTest()
{
var result = controller.Action();
result.ShouldBeRedirectionTo(
new
{
controller = "ControllerName",
action = "Index"
}
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8268 次 |
| 最近记录: |