2015-09-06 129 views
0

我一直在創建一個單元測試,但似乎失敗了。任何人都可以幫助我爲這個控制器創建一個單元測試嗎?單元測試mvc登錄

我已經嘗試過各種方法。

public class logInController : Controller 
    { 
     [HttpPost] 
     public ActionResult Index(logInModel model) 
     { 
      if(ModelState.IsValid) 
      { 
       int match = 0; 

       sqlConn = new SqlConnection(sqlConnString); 

       sqlComm = new SqlCommand("spLogin", sqlConn); 
       sqlComm.CommandType = CommandType.StoredProcedure; 
       sqlComm.Parameters.AddWithValue("@userName", model.Username); 
       sqlComm.Parameters.AddWithValue("@password", model.Password); 

       SqlParameter userMatch = new SqlParameter("@userMatch", SqlDbType.Int); 
       userMatch.Direction = ParameterDirection.Output; 
       sqlComm.Parameters.Add(userMatch); 

       sqlConn.Open(); 
       sqlComm.ExecuteNonQuery(); 

       match = Convert.ToInt32(sqlComm.Parameters["@userMatch"].Value); 
       sqlConn.Close(); 

       if (match != 0) 
       { 
        FormsAuthentication.SetAuthCookie(model.Username, false); 
        return RedirectToAction("index","home"); 
       } 
       else 
        ModelState.AddModelError("", "Invalid username or password"); 
      } 
      return View(); 
     } 
    } 

在這個時候我想要這個。

public void LoginTest() 
     { 
      var controller = new logInController(); 
      var loginmodel = new logInModel 
      { 
       Username = "arwinortiz", 
       Password = "123456" 
      }; 
      FormsAuthentication.SetAuthCookie(loginmodel.Username, false); 
      var result = (RedirectToRouteResult)controller.Index(loginmodel); 
      result.RouteValues["action"].Equals("index"); 
      result.RouteValues["controller"].Equals("home"); 
      Assert.AreEqual("index", result.RouteValues["action"]); 
      Assert.AreEqual("home", result.RouteValues["controller"]); 
     } 
+0

向我們展示您的嘗試,我們不打算爲您建立整個模型。 –

+1

你需要從控制器中抽取出分貝數據。只是說... –

回答

0

首先,你需要抽象你的數據庫和窗體身份驗證調出到了自己的擔憂/接口,以便他們可以嘲笑。 (羞羞..... ....)

public interface IAuthenticationService { 
    bool Authenticate(string username, string password); 
} 

public interface IFormsAuthenticationService { 
    void SetAuthCookie(string userName, bool createPersistentCookie); 
    void SignOut(); 
} 

與做你的控制器可以重構到

public class logInController : Controller { 
    private IAuthenticationService authenticator; 
    private IFormsAuthenticationService formsAuthentication; 

    public MvcTestsController(IAuthenticationService userAuthentication, IFormsAuthenticationService formsAuthentication) { 
     this.authenticator = userAuthentication; 
     this.formsAuthentication = formsAuthentication; 
    } 

    [HttpPost] 
    public ActionResult Index(logInModel model) { 
     if (ModelState.IsValid) { 
      bool match = authenticator.Authenticate(model.Username, model.Password); 
      if (match) { 
       formsAuthentication.SetAuthCookie(model.Username, false); 
       return RedirectToAction("index", "home"); 
      } else 
       ModelState.AddModelError("", "Invalid username or password"); 
     } 
     return View(); 
    } 
} 

接下來我們寫的登錄單元測試。

注意:我使用Moq來嘲笑依賴關係,FluentAssertions來聲明結果。

[TestMethod] 
public void LoginTest() { 
    //Arrange 
    var loginmodel = new logInModel { 
     Username = "arwinortiz", 
     Password = "123456" 
    }; 
    var mockAuthenticator = new Mock<IAuthenticationService>(); 
    mockAuthenticator 
      .Setup(x => x.Authenticate(It.Is<string>(s => s == loginmodel.Username), It.Is<string>(s => s == loginmodel.Password))) 
      .Returns(true); 
    var mockFormsAuthentication = new Mock<IFormsAuthenticationService>(); 

    bool isAuthCookieSet = false; 
    mockFormsAuthentication 
     .Setup(x => x.SetAuthCookie(It.Is<string>(s => s == loginmodel.Username), It.IsAny<bool>())) 
     .Callback(() => { isAuthCookieSet = true; }); 

    var controller = new logInController(mockAuthenticator.Object, mockFormsAuthentication.Object); 

    //Act 
    var result = (System.Web.Mvc.RedirectToRouteResult)controller.Index(loginmodel); 

    //Assert (using FluentAssertions) 
    result.Should().NotBeNull(because: "the result should have redirected for entered user "); 
    result.RouteValues["action"].ShouldBeEquivalentTo("index", because: "the redirection was to home.index action"); 
    result.RouteValues["controller"].ShouldBeEquivalentTo("home", because: "the result should redirect to home controller"); 
    isAuthCookieSet.Should().BeTrue(because: "auth cookie is set if the user was authenticated"); 
}