c# – 如何单元测试使用MVC ASP.Net返回正确的视图?

c# – 如何单元测试使用MVC ASP.Net返回正确的视图?,第1张

概述我是MVC,单元测试,模拟和TDD的新手.我尽量遵循最佳做法. 我为控制器编写了单元测试,如果返回正确的视图,我无法测试.如果我使用ViewResult.ViewName,如果控制器中没有指定视图名称,则测试总是失败.如果我在控制器中指定了ViewName,测试总是通过,即使视图不存在. 我也试过测试Response.Status代码,但这总是返回200(代码取自Darin Dimitrov的答案 我是MVC,单元测试,模拟和TDD的新手.我尽量遵循最佳做法.

我为控制器编写了单元测试,如果返回正确的视图,我无法测试.如果我使用VIEwResult.VIEwname,如果控制器中没有指定视图名称,则测试总是失败.如果我在控制器中指定了VIEwname,测试总是通过,即使视图不存在.

我也试过测试Response.Status代码,但这总是返回200(代码取自Darin Dimitrov的答案为MVC3 unit testing response code).我的目标是经典的红色,绿色重构,当创建一个新的视图,避免404和system.invalIDOperationException错误,当上线,这是可能吗?

下面的代码

public class BUGStatusController : Controller{    public ActionResult Index(){        return VIEw(); // Test always fails as vIEw name isn’t specifIEd even if the correct vIEw is returned.    }    public ActionResult Create(){        return VIEw("Create"); // Test always passes as vIEw name is specifIEd even if the vIEw doesn’t exist.    }}[TestFixture]public class BUGStatusTests{        private VIEwResult GetVIEwResult(Controller controller,string controllerMethodname){        Type type = controller.GetType();        ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);        object instance = constructor.Invoke(new object[] {});        MethodInfo[] methods = type.getmethods();        MethodInfo methodInfo = (from method in methods                                where method.name == controllerMethodname                                                    && method.GetParameters().Count() == 0                                select method).FirstOrDefault();        Assert.IsNotNull(methodInfo,"The controller {0} has no method called {1}",type.name,controllerMethodname);        VIEwResult result = methodInfo.Invoke(instance,new object[] {}) as VIEwResult;        Assert.IsNotNull(result,"The VIEwResult is null,controller: {0},vIEw: {1}",controllerMethodname);        return result;    }    [Test]    [TestCase("Index","Index")]    [TestCase("Create","Create")]    public voID TestExpectedVIEwIsReturned(string expectedVIEwname,string controllerMethodname){        VIEwResult result = GetVIEwResult(new BUGStatusController(),controllerMethodname);        Assert.AreEqual(expectedVIEwname,result.VIEwname,"Unexpected vIEw returned,CONTRolLER_name,expectedVIEwname);    }    [Test]    [TestCase("Index","Create")]    public voID TestExpectedStatusCodeIsReturned(string expectedVIEwname,string controllerMethodname)    {        var controller = new BUGStatusController();        var request = new @R_502_6822@Request("","@R_502_6822@://localhost:58687/","");        var response = new @R_502_6822@Response(TextWriter.Null);        var @R_502_6822@Context = new @R_502_6822@Contextwrapper(new @R_502_6822@Context(request,response));        controller.ControllerContext = new ControllerContext(@R_502_6822@Context,new RouteData(),controller);        ActionResult result = GetVIEwResult(controller,controllerMethodname);        Assert.AreEqual(200,response.StatusCode,"Failed to load " + expectedVIEwname + " Error: "  + response.StatusDescription);    }}
解决方法

I’m new to MVC,Unit Testing,Mocking and TDD. I’m trying to follow best practice as closely as possible.

我感到开心,越来越多的开发人员开始为他们的代码编写单元测试,所以恭喜你走在正确的道路上.

if I don’t specify the vIEw name in the controller. If I do specify the VIEwname in the controller the test always passes,even if the vIEw doesn’t exist.

当您在VIEw方法中未指定视图名称时,将指示MVC引擎呈现默认视图,例如

public ActionResult Index() { return VIEw(); }

上面的代码将返回一个空的视图名,这意味着渲染的视图将是 *** 作的名称,在这种情况下它将是Index.

因此,如果要测试一个 *** 作返回默认视图,则必须测试返回的视图名称是否为空

Test always passes as vIEw name is specifIEd even if the vIEw doesn’t exist.

为了解释这里发生了什么,我将首先解释动作过滤器的工作原理.

基本上有四种类型的滤波器

>异常过滤器
>授权过滤器
>动作过滤器
>结果过滤器

我会专注于行动和结果过滤器

动作过滤器由IActionFilter接口定义

public interface IActionFilter{    // Summary:    //     Called after the action method executes.    //    voID OnActionExecuted(ActionExecutedContext filterContext);    //    // Summary:    //     Called before an action method executes.    //    voID OnActionExecuting(ActionExecutingContext filterContext);}

结果过滤器由IResultFilter接口定义

public interface IResultFilter{    // Summary:    //     Called after an action result executes.    //    voID OnResultExecuted(ResultExecutedContext filterContext);    //    // Summary:    //     Called before an action result executes.    //    voID OnResultExecuting(ResultExecutingContext filterContext);}

当执行控制器的动作时,按以下特定顺序执行以下过滤器:

IActionFilter.OnActionExecutingIActionFilter.OnActionExecutedIResultFilter.OnResultExecutingIResultFilter.OnResultExecuted

当执行一个动作时,另一个组件负责处理从您的 *** 作返回的ActionResult,并呈现正确的HTML以将其发送回客户端,这是处理结果时

这种干涉分离的关键是美观和关键,允许我们单位测试我们的控制器的行动,否则,如果它们耦合,我们将无法单独测试单独测试结果的行动

现在,RazorVIEwEngine尝试在执行 *** 作后(当处理结果时)找到一个视图,这就是为什么您的测试返回true,即使物理视图不存在.这是预期的行为,并记住您需要隔离测试控制器的 *** 作.只要您在单元测试中断言预期视图呈现,您就可以完成单元测试.

如果您想声明物理视图存在,那么您将会讨论一些特定的集成测试:功能测试或用户验收测试 – 这些测试需要使用浏览器实例化您的应用程序,而不是单元测试

现在您可以手动编写单元测试(如果您进入单元测试世界,这是一个很好的练习),但是,我想推荐一些可以帮助您编写单元的MVC测试框架测试真的很快

> https://github.com/robdmoore/FluentMVCTesting
> http://mvccontrib.codeplex.com/wikipage?title=TestHelper&referringTitle=Documentation

关于这些框架的一些个人评论

根据我的经验,MVC Contrib具有比Fluent MVC测试更多的功能,由于我使用MVC 4,我无法在Visual Studio 2012中使用它,所以我使用两者的组合(这是一个脏解决方法,直到我找到一个更好的方法)

这就是我所做的:

var testControllerBuilder = new TestControllerBuilder(); // this is from MVC Contribvar controller = new MovIEsController(    this.GetMock<IMovIEqueryManager>().Object);testControllerBuilder.InitializeController(controller); // this allows me to use the Session,Request and Response objects as mock objects,again this is provIDed by the MVC Contrib framework// I should be able to call something like this but this is not working due to some problems with DLL versions (hell DLL's) between MVC Controb,Moq and MVC itself// testControllerBuilder.CreateController<MovIEsController>();controller.WithCallTo(x => x.Index(string.Empty)).ShouldRenderdefaultview(); // this is using Fluent MVC Testing// again instead of the above line I Could use the MVC Contrib if it were working....// var res = sut.Index(string.Empty);// res.AssertVIEWrendered().ForVIEw("Index");

我希望这有助于=)快乐的编码!

总结

以上是内存溢出为你收集整理的c# – 如何单元测试使用MVC ASP.Net返回正确的视图?全部内容,希望文章能够帮你解决c# – 如何单元测试使用MVC ASP.Net返回正确的视图?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1259223.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存