尝试测试共享会话数据的两个控制器操作。 MVC

时间:2016-01-18 22:06:24

标签: asp.net-mvc unit-testing

我正在尝试编写一个检查两个控制器操作的单元测试。这些控制器操作依赖于Session变量。到目前为止,我有这个:

单元测试:

[TestMethod]
public void TableOfContentReportTest()
{
    // Arrange
    var fakeDb = TestFakes.SetupFakeDbContext();
    var controller = TestFakes.ProjectController(fakeDb);

    // Act
    var selectedSubs = AutoMapper.Mapper.Map<ProjectSubmissionViewModel>(fakeDb.ProjectSubmission.FirstOrDefault());
    selectedSubs.Selected = true;
    controller.Session["SelectedSubmissions"] = new List<ProjectSubmissionViewModel> {selectedSubs};

    var result = controller.SubmissionIndex("ProjectTitle", true,1, 10,"","","","","",
        StaticStrings.Report_TableOfContents) as ViewResult;

    // Assert
    Assert.IsNotNull(result);

    var testSession = controller.processReport();
}

TestFakes.ProjectController为控制器设置会话,如下所示:

//...
var session = new Mock<HttpSessionStateBase>();
var context = new Mock<HttpContextBase>(MockBehavior.Strict);
context.SetupGet(x => x.Session).Returns(session.Object);

var rc = new RequestContext(context.Object, new RouteData());
var controller = new ProjectController(fakeDb);
controller.ControllerContext = new ControllerContext(rc, controller);
//...

SubmissionIndex设置Session变量:

public virtual ActionResult SubmissionIndex(
    string sortBy = "ProjectTitle", 
    bool ascending = true,
    int page = 1, 
    int pageSize = 10,
    string projectId = "",
    string submissiontitle = "",
    string firstname = "",
    string lastname = "",
    string email = "",
    string showreport = "")
{
    var selectedSubmissions = Session["SelectedSubmissions"] as ICollection<ProjectSubmissionViewModel>;
    //... Uses selectedSubmissions to build bookResources and chapters
    Session["reportData"] = viewModel.GetContentsReport(bookResources, chapters);
    //...
}

在运行时,代码可以正常工作。通过单元测试,SubmissionIndex将Session [&#34; SelectedSubmissions&#34;]视为null。

我设置假控制器的会话是错误的吗?如何在测试时使用Session?

更新:我经常从重定向调用SubmissionIndex操作:
Session["SelectedSubmissions"] = model.Submissions.Where(s => s.Selected).ToList(); return RedirectToAction("SubmissionIndex", "Project", routeValues);

1 个答案:

答案 0 :(得分:0)

你是否尝试过直接嘲笑它:

var session = new Mock<HttpSessionStateBase>();
var myCollection = new ICollection<ProjectSubmissionViewModel> { object1, object2... etc };
session.Setup(x => x["SelectedSubmissions"]).Returns(myCollection);

或者您甚至可以根据通用输入返回

session.Setup(x => x[It.IsAny<string>()]).Returns(myCollection);

实施例

private ProjectController controller;

[TestSetup]
public void Setup()
{
    var dbMock = new Mock<db>();

    //Set up properties etc 
    var context = new Mock<HttpContextBase>(MockBehavior.Strict);
    context.SetupGet(x => x.Session["SelectedSubmissions"]).Returns(object1);
    context.SetupGet(x => x.Session["reportStuff"]).Returns(object2);
    controller = new ProjectController(dbMock.Object);
}

[TestMethod]
public void TableOfContentReportTest()
{
    var result = controller.SubmissionIndex(
              "ProjectTitle",
              true,
              1, 10,"","","","","",
              StaticStrings.Report_TableOfContents) as ViewResult;

    // Assert
    Assert.IsNotNull(result);

    var testSession = controller.processReport();
}