如何在c#Mvc中编写单元测试?方法有会话

时间:2016-07-25 10:03:46

标签: c# asp.net-mvc unit-testing

我得到了错误。

  

"类型' System.NullReferenceException'的例外情况发生在   Effort Estimation.dll但未在用户代码中处理   information:对象引用未设置为对象的实例。 "

在控制器中我有一个名为Login的方法。在那个方法中我们使用session。那么如何编写单元测试呢?在运行单元测试代码时,它转到主csharp代码并进入方法并在会话声明中停止。 任何人都知道解决方案尽快解决它。

我的单元测试代码,我试过的是,LoginModel类有2个我在那里分配的变量。

[TestMethod]
public void Login1() //Bug
{
    LoginController log = new LoginController();
    LoginModel logModel = new LoginModel ();
    logModel.UserName = "20079199";
    logModel.Password = "123456";
    var result = log.Login(logModel) as ViewResult;
    Assert.AreEqual("HomePage", result);

}

[HttpPost]
public ActionResult Login(LoginModel lVM)
{
    LoginViewModel model = UM.Authentication(lVM);
    if (model.UserId > 0)
    {
        Session["LoginMessage"] =  model.UserName;
        Session["UserID"] = model.UserId;

        IDataHelper ex = new DataHelper();

        return RedirectToAction("HomePage", "Newcontroller");
    }
    else
    {
        Session["LoginMessage"] = "Invalid UserName and Password";
        return RedirectToAction("Login", "Login");
    }
}

1 个答案:

答案 0 :(得分:2)

我认为你有三个选择:

1)使用HttpContextBase并模拟控制器中需要的内容

2)创建一个可测试的LoginController,它继承自LoginController,例如

public class TestAbleLoginController : LoginController{}

执行此操作后,将用新方法设置会话的代码打包,然后在可测试控制器中覆盖该方法,这样如果您不需要,则不会设置会话。

e.g。

protected internal override SetLoginInfo(){ //do nothing}

虽然实际代码确实

protected virtual SetLoginInfo(){ Session["LoginMessage"]...}

3)包装代码以访问另一个对象中的会话,并通过构造函数将其注入。所以你可以用你需要的东西定义像IUserSession这样的界面,然后在你的测试中模拟这个界面,这样它就不会做任何事情,比如

var userSession = MockRepository.GenerateStub<IUserSession>();