我在使用现有的 AccountController(由 MVC 制作)测试登录方法时遇到问题...
我有这个简单的测试方法:
[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 );
}
以及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 );
}
上述方法不是我定义/修改的。刚在创建 asp.net mvc 项目时创建。
问题在行
if ( MembershipService.ValidateUser( model.UserName,model.Password ) ) {
虽然我提供了正确的登录信息,但它返回总是 false。
我的错误在哪里?
最佳答案
首先,不要在测试中使用if
语句和其他条件逻辑。也不要在测试中使用具体类。如果这个测试会失败,你怎么知道为什么?什么坏了 - Controller 或 AccountMembershipService
?使用可以模拟的抽象依赖项。
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
}
}
还有你的测试:
[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."));
}
有趣的是,您不关心传递给 Controller 的登录信息是什么。您模拟来自成员(member)服务的响应,它说登录不正确。
更多测试:
[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"));
}
关于c# - 在 asp.net mvc 3 中登录的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11612608/