I have a problem testing a logon method using existing AccountController (made by MVC)...
I have this simple test method:
[TestMethod]
public void LogOnTest1() {
AccountController controller = new AccountController();
LogOnModel logonModel = new LogOnModel();
logonModel.UserName = "test";
logonModel.Password = "test1234";
if ( controller.MembershipService == null ) {
controller.MembershipService = new AccountMembershipService();
}
if ( controller.FormsService == null ) {
controller.FormsService = new FormsAuthenticationService();
}
var result = controller.LogOn( logonModel, "" ) as ViewResult;
Assert.AreEqual( "Index", result.ViewName );
}
and the method defined in AccountController
:
[HttpPost]
public ActionResult LogOn( LogOnModel model, string returnUrl ) {
if ( ModelState.IsValid ) {
if ( MembershipService.ValidateUser( model.UserName, model.Password ) ) {
FormsService.SignIn( model.UserName, model.RememberMe );
if ( !string.IsNullOrEmpty( returnUrl ) ) {
return Redirect( returnUrl );
} else {
return RedirectToAction( "Index", "Home" );
}
} else {
ModelState.AddModelError( "", "The user name or password provided is incorrect." );
}
}
// If we got this far, something failed, redisplay form
return View( model );
}
The above method is not defined/modified by me. Just created by when create an asp.net mvc project.
The problem is at line
if ( MembershipService.ValidateUser( model.UserName,model.Password ) ) {
which returns always false though I provided correct login info.
Where is my mistake ?
First of all, do not use if
statements and other conditional logic in your tests. Also do not use concrete classes in your tests. If this test will fail, how will you know why? What was broken - controller or AccountMembershipService
? Use abstract dependencies, which could be mocked.
public class AccountController : Controller
{
private IMembershipService _membershipService;
private IFormsService _formsService;
public AccountController(IMembershipService membershipService,
IFormsService formsService)
{
_membershipService = membershipService;
_formsService = formsService;
}
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
// implementation goes here
}
}
And your tests:
[Test]
public void ShouldNotAcceptInvalidUser()
{
// Arrange
Mock<IMembershipService> membership = new Mock<IMembershipService>();
membership.Setup(m => m.ValidateUser(It.IsAny<string>(), It.IsAny<string>()))
.Returns(false);
Mock<IFormsService> forms = new Mock<IFormsService>();
var logonModel = new LogOnModel() { UserName = "", Password = "" };
var controller = new AccountController(membership.Object, forms.Object);
// Act
var result = controller.LogOn(logonModel, "") as ViewResult;
// Assert
Assert.That(result.ViewName, Is.EqualTo("Index"));
Assert.False(controller.ModelState.IsValid);
Assert.That(controller.ModelState[""],
Is.EqualTo("The user name or password provided is incorrect."));
}
Interesting here is that you don't care which logon info you passed to controller. You mock response from membership service, which says logon was incorrect.
FEW TESTS MORE:
[Test]
public void ShouldRedisplayViewWhenModelIsNotValid()
{
// Arrange
Mock<IMembershipService> membership = new Mock<IMembershipService>();
Mock<IFormsService> forms = new Mock<IFormsService>();
var model = new LogOnModel() { UserName = "", Password = "" };
var controller = new AccountController(membership.Object, forms.Object);
controller.ModelState.AddModelError("key", "error message");
// Act
var result = controller.LogOn(model, "") as ViewResult;
// Assert
Assert.That(result.ViewName, Is.EqualTo("LogOn"));
}
[Test]
public void ShouldSignInAndRedirectToIndex()
{
// Arrange
Mock<IMembershipService> membership = new Mock<IMembershipService>();
membership.Setup(m => m.ValidateUser(It.IsAny<string>(), It.IsAny<string>()))
.Returns(true);
Mock<IFormsService> forms = new Mock<IFormsService>();
var model = new LogOnModel() { UserName = "", Password = "" };
var controller = new AccountController(membership.Object, forms.Object);
controller.ModelState.AddModelError("key", "error message");
// Act
var result = controller.LogOn(model, "") as ViewResult;
// Assert
forms.Verify(f => f.SignIn(model.UserName, model.RememberMe));
Assert.That(result.ViewName, Is.EqualTo("Index"));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.