繁体   English   中英

为什么在运行单元测试时出现以下错误:“ System.NullReferenceException:对象引用未设置为对象的实例。”

[英]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中进行表单身份验证的好帖子。

通过测试的最简单方法是使用ControllerUser属性。 您还可以通过创建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 ,因此resultnull

由于您取消引用null result.ViewName失败。

您需要查看Index的定义并确定其返回的对象类型。 另外,您可以为controller.Index()创建一个变量,然后查看其类型。

编辑:

更深入地研究Index() ,似乎您所依赖的数据点可能不可用。 控制器依靠其框架(在本例中为您的测试框架)来提供某些组件,IIRC, SessionViewBag是其中的两个组件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM