带有HttpContext的ASP.NET MVC单元测试控制器

amu*_*rra 32 asp.net-mvc unit-testing

我正在尝试为我的一个控制器编写一个单元测试来验证视图是否正确返回,但是这个控制器有一个访问HttpContext.Current.Session的基本控制器.每次我创建一个我的控制器的新实例都会调用basecontroller构造函数,并且测试失败并在HttpContext.Current.Session上出现空指针异常.这是代码:

public class BaseController : Controller
{       
    protected BaseController()
    {
       ViewData["UserID"] = HttpContext.Current.Session["UserID"];   
    }
}

public class IndexController : BaseController
{
    public ActionResult Index()
    {
        return View("Index.aspx");
    }
}

    [TestMethod]
    public void Retrieve_IndexTest()
    {
        // Arrange
        const string expectedViewName = "Index";

        IndexController controller = new IndexController();

        // Act
        var result = controller.Index() as ViewResult;

        // Assert
        Assert.IsNotNull(result, "Should have returned a ViewResult");
        Assert.AreEqual(expectedViewName, result.ViewName, "View name should have been {0}", expectedViewName);
    }
Run Code Online (Sandbox Code Playgroud)

关于如何模拟(使用Moq)在基本控制器中访问的Session的任何想法,以便后代控制器中的测试将运行?

Mar*_*ann 65

除非你使用Typemock或Moles,否则你不能.

在ASP.NET MVC中,您不应该使用HttpContext.Current.将您的基类更改为使用ControllerBase.ControllerContext - 它具有HttpContext属性,该属性公开可测试的HttpContextBase类.

这是一个如何使用Moq设置Mock HttpContextBase的示例:

var httpCtxStub = new Mock<HttpContextBase>();

var controllerCtx = new ControllerContext();
controllerCtx.HttpContext = httpCtxStub.Object;

sut.ControllerContext = controllerCtx;

// Exercise and verify the sut
Run Code Online (Sandbox Code Playgroud)

其中sut代表被测系统(SUT),即您要测试的控制器.


Gra*_*ton 5

如果您使用的是Typemock,则可以执行以下操作:

Isolate.WhenCalled(()=>controller.HttpContext.Current.Session["UserID"])
.WillReturn("your id");
Run Code Online (Sandbox Code Playgroud)

测试代码如下所示:

[TestMethod]
public void Retrieve_IndexTest()
{
    // Arrange
    const string expectedViewName = "Index";

    IndexController controller = new IndexController();
    Isolate.WhenCalled(()=>controller.HttpContext.Current.Session["UserID"])
    .WillReturn("your id");
    // Act
    var result = controller.Index() as ViewResult;

    // Assert
    Assert.IsNotNull(result, "Should have returned a ViewResult");
    Assert.AreEqual(expectedViewName, result.ViewName, "View name should have been {0}", expectedViewName);
}
Run Code Online (Sandbox Code Playgroud)