[英]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?
I have never run Unit testing before and I am just trying to run an example I have found on the net over and over in regards to the view name. 我以前从未进行过单元测试,而只是试图反复运行一个在网络上发现的有关视图名称的示例。
My Test code is: 我的测试代码是:
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);
}
}
}
The error I am getting is System.NullReferenceException: Object reference not set to an instance of an object.
我得到的错误是
System.NullReferenceException: Object reference not set to an instance of an object.
on the Line that sets the view result. 在设置视图结果的行上。
What do I need to do to get this working? 我需要做什么才能使它正常工作? Is there anything out there that is more descriptive as to Unit testing examples?
有没有什么可以比单元测试示例更具描述性?
Edit one 编辑一个
Controller Code for Index 索引的控制器代码
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");
}
}
You're using the controllers Session
property, which will be null because you haven't supplied the controller with the information it needs to create it. 您正在使用控制器的
Session
属性,该属性为null,因为尚未向控制器提供创建控制器所需的信息。 This information is normally supplied automatically when running under the Asp.Net pipeline. 在Asp.Net管道下运行时,通常会自动提供此信息。 You can verify this by debugging and stepping into (F11) the
Index
action method and hovering over Session
. 您可以通过调试并进入(F11)
Index
操作方法并将鼠标悬停在Session
上来进行验证。
You need to set the ControllerContext property of the controller. 您需要设置控制器的ControllerContext属性。 Even better would be to use the Authorize attribute on your action method / controller.
更好的方法是在操作方法/控制器上使用Authorize属性。 This is a good post about how to do Forms authentication in MVC.
这是一篇有关如何在MVC中进行表单身份验证的好帖子。
The simplest way to get your test going though is to use the Controller
's User
property. 通过测试的最简单方法是使用
Controller
的User
属性。 You also do this by creating an instance of ControllerContext
and setting its HttpContext
property, probably by Moq'ing HttpContextBase so that you can return whatever IPrincipal
you want. 您还可以通过创建
ControllerContext
实例并设置其HttpContext
属性来执行此操作,这可能是通过对HttpContextBase进行Moq处理来实现的,以便您可以返回所需的任何IPrincipal
。
So this is what you'd need to add after you new up your controller (I'm showing you with the Moq framework, but the VS UnitTest tools might provide its own way to do mocks. Either is fine): 因此,这是您在新建控制器后需要添加的内容(我向您展示了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;
After you have all that setup, then you can safely call the action method you're testing. 完成所有设置后,即可安全地调用要测试的操作方法。
controller.Index()
is not returning a ViewResult
and thus result
is null
. controller.Index()
没有返回ViewResult
,因此result
为null
。
result.ViewName
is then failing as you are dereferencing null
. 由于您取消引用
null
result.ViewName
失败。
You need to look at the definition of Index
and determine what type of object it is returning. 您需要查看
Index
的定义并确定其返回的对象类型。 Alternatively you can create a variable for controller.Index()
and see what type it has. 另外,您可以为
controller.Index()
创建一个变量,然后查看其类型。
EDIT: 编辑:
Taking a deeper look at Index()
it appears that you are relying on some data points that might not be available. 更深入地研究
Index()
,似乎您所依赖的数据点可能不可用。 The controller is relying on its framework (in this case your test framework) to provide certain pieces, IIRC the Session
and ViewBag
are two of those pieces. 控制器依靠其框架(在本例中为您的测试框架)来提供某些组件,IIRC,
Session
和ViewBag
是其中的两个组件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.