![](/img/trans.png)
[英]MVC: By SelectListItem I get “System.NullReferenceException: Object reference not set to an instance of an object.” error
[英]Why am I getting the following error: “System.NullReferenceException: Object reference not set to an instance of an object.” when I run a Unit Test?
我以前从未进行过单元测试,而只是试图反复运行一个在网络上发现的有关视图名称的示例。
我的测试代码是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Admin.Web.API.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Mvc;
namespace Admin.Web.API.Controllers.Tests
{
[TestClass()]
public class HomeControllerTests
{
[TestMethod()]
public void IndexTest()
{
HomeController controller = new HomeController();
var result = controller.Index() as ViewResult;
Assert.AreEqual("Index", result.ViewName);
}
}
}
我得到的错误是System.NullReferenceException: Object reference not set to an instance of an object.
在设置视图结果的行上。
我需要做什么才能使它正常工作? 有没有什么可以比单元测试示例更具描述性?
编辑一个
索引的控制器代码
public ActionResult Index()
{
if (this.Session["UserID"] == null)
{
return View("Login");
}
else
{
ViewBag.Title = "Index";
ViewBag.SiteID = this.Session["SiteID"];
ViewBag.AssemblyVersion = this.Session["AssemblyVersion"];
ViewBag.UserFirstName = this.Session["FirstName"];
GoogleAnalytics _oGoogleAnalytics = new GoogleAnalytics();
ViewBag.GoogleAnalytics = _oGoogleAnalytics.GetGoogleAnalytics(
this.Session["GoogleAnalyticsAccountCode"].ToString(),
Convert.ToBoolean(this.Session["UseGoogleAnalytics"]));
return View("Index");
}
}
您正在使用控制器的Session
属性,该属性为null,因为尚未向控制器提供创建控制器所需的信息。 在Asp.Net管道下运行时,通常会自动提供此信息。 您可以通过调试并进入(F11) Index
操作方法并将鼠标悬停在Session
上来进行验证。
您需要设置控制器的ControllerContext属性。 更好的方法是在操作方法/控制器上使用Authorize属性。 这是一篇有关如何在MVC中进行表单身份验证的好帖子。
通过测试的最简单方法是使用Controller
的User
属性。 您还可以通过创建ControllerContext
实例并设置其HttpContext
属性来执行此操作,这可能是通过对HttpContextBase进行Moq处理来实现的,以便您可以返回所需的任何IPrincipal
。
因此,这是您在新建控制器后需要添加的内容(我向您展示了Moq框架,但VS UnitTest工具可能提供了自己的模拟方法,两种都可以):
var principalMock = new Mock<IPrincipal>(); // Mock<T> is from the Moq framework
principalMock.Setup(x => x.IsAuthenticated).Returns(true); // Or false, depending on what you're testing
var httpContextMock = new Mock<HttpContextBase>();
httpContextMock.Setup(x => x.User).Returns(principalMock.Object);
var controllerContext = new ControllerContext { HttpContext = contextMock.Object };
conrollerContext.Controller = controller;
controller.ControllerContext = controllerContext;
完成所有设置后,即可安全地调用要测试的操作方法。
controller.Index()
没有返回ViewResult
,因此result
为null
。
由于您取消引用null
result.ViewName
失败。
您需要查看Index
的定义并确定其返回的对象类型。 另外,您可以为controller.Index()
创建一个变量,然后查看其类型。
编辑:
更深入地研究Index()
,似乎您所依赖的数据点可能不可用。 控制器依靠其框架(在本例中为您的测试框架)来提供某些组件,IIRC, Session
和ViewBag
是其中的两个组件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.