单元测试和会话?

时间:2011-12-02 18:57:08

标签: c# unit-testing session mocking moq

我有一个类似的例程:

public bool IsValidEmployee(string email, string password)
{
  bool valid = false;
  var employee = dataAccess.GetEmployee(email, password);

  if(employee! = null)
   {
      valid = true;
      HttpContext.Current.Session["Employee"] = employee;
   }

   return valid;
}

我的单元测试:

[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("C:\Projects", "/")]
[UrlToTest("http://localhost:59349/")]
public void GetEmployeeTest()
{
   Domain target = new Domain();        

   var mockHttpContext = new Mock<HttpContextBase>();
   mockHttpContext.SetupSet(c => c.Session["Employee"] = It.IsAny<object>());

   Assert.IsTrue(target.IsValidEmployee("sam@gmail.com", "test");                
 }

代码失败为

  

上的对象空引用'HttpContext.Current.Session [“Employee”] = employee;'

有关我如何解决此错误的任何建议?

4 个答案:

答案 0 :(得分:2)

我不相信只是嘲笑HttpSession足以让你的方法中的会话采取模拟行为。你需要一种方法来注入这种依赖。

您可以重新设计您的函数以将会话对象作为参数接收。这将使您的方法可测试

例如

public bool IsValidEmployee(string email, string password, HttpSessionStateBase session)
{
  bool valid = false;
  var employee = dataAccess.GetEmployee(email, password);

  if(employee! = null)
   {
      valid = true;
      session["Employee"] = employee;
   }

   return valid;
}

此外,您可以创建一个“SessionManager”,它可以实现ISessionManager,它将包含您对会话状态的所有访问权限并将其传递给它,使其更加可测试,从而解除了如何以及在何处保持会话状态与验证员工的责任。

答案 1 :(得分:1)

Moles将允许您拦截并将呼叫替换为会话。

http://research.microsoft.com/en-us/projects/pex/getstarted.pdf

如果可能的话,应该避免使用会话,因为它会给服务器带来负担。

该代码看起来很容易出错,但也许这就是为什么要添加单元测试。

答案 2 :(得分:0)

我认为你还需要为会议模拟getter ......

public void GetEmployeeTest()
    {
        Domain target = new Domain();
        var mockHttpContext = new Mock<HttpContextBase>();
        var mockSession = new Mock<HttpSessionStateBase>();
        mockHttpContext.SetupGet(c => c.Session).Returns(mockSession.Object);
        mockHttpContext.SetupSet(c => c.Session["Employee"] = It.IsAny<object>());
        Assert.IsTrue(target.IsValidEmployee("sam@gmail.com", "test"));
    }

答案 3 :(得分:0)

哪个代码失败了?这是由于您的方法中的错误导致测试失败,还是测试代码本身出现错误?

无论你如何改进测试(这可能听起来有点明显),但我想知道你是否在测试方法的设置行上设置了一个断点,并且实际检查了该对象你试图赋值为null?如果是这种情况,您需要检查您的设置,并且正如其他人可能已经说过您可能需要模拟您的会话,以确保您的测试的设置部分不会失败。

干杯。