使用Moq模拟FormsAuthentication.SetAuthCookie

9

您好,我正在对我的ASP.Net MVC2项目进行一些单元测试。我使用Moq框架。在我的LogOnController中,

[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl = "")
{
  FormsAuthenticationService FormsService = new FormsAuthenticationService();
  FormsService.SignIn(model.UserName, model.RememberMe);

 }

在 FormAuthenticationService 类中,
public class FormsAuthenticationService : IFormsAuthenticationService
    {
        public virtual void SignIn(string userName, bool createPersistentCookie)
        {
            if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot     be null or empty.", "userName");
            FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
        }
        public void SignOut()
        {
            FormsAuthentication.SignOut();
        }
    }

我的问题是如何避免执行 "

"。
FormsService.SignIn(model.UserName, model.RememberMe);

我需要翻译的是这行文字。或者有没有一种方法可以使用Moq进行测试?

 FormsService.SignIn(model.UserName, model.RememberMe);

使用Moq框架,在不改变我的ASP.Net MVC2项目的情况下。


SUT(被测试系统)是“LogOnController”还是“FormsAuthenticationService”?如果是前者,则应为“FormsAuthenticationService”提供一个虚拟对象,并验证其上是否调用了“SignIn”方法。后者更难进行单元测试,因为它需要当前的HttpContext来添加cookie(到HttpResponse)。 - Russ Cam
我想测试LogOnController。我尝试模拟FormsService.SignIn(model.UserName, model.RememberMe)的方式如下: var formService=new Mock<FormsAuthenticationService>(); 但是formservice.SignIn没有返回任何内容。我该如何避免执行那行代码或者如何模拟那行代码。我不知道如何使用Moq来模拟它。 - Dilma
1个回答

11

在你的LogOnController中注入IFormsAuthenticationService依赖,就像这样:

private IFormsAuthenticationService formsAuthenticationService;
public LogOnController() : this(new FormsAuthenticationService())
{
}

public LogOnController(IFormsAuthenticationService formsAuthenticationService) : this(new FormsAuthenticationService())
{
    this.formsAuthenticationService = formsAuthenticationService;
}

第一个构造函数是为了在运行时使用正确的 IFormsAuthenticationService 实例而为框架而设计的。

现在在你的测试中,通过传递模拟对象,使用另外一个构造函数创建LogonController实例,如下所示:

var mockformsAuthenticationService = new Mock<IFormsAuthenticationService>();
//Setup your mock here

将您的操作代码更改为使用私有字段formsAuthenticationService,如下所示。

[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl = "")
{
    formsAuthenticationService.SignIn(model.UserName, model.RememberMe);
}
希望这可以帮到你。我为你省略了模拟设置。如果你不确定如何设置,请告诉我。

谢谢Suhas。由于我是ASP.Net单元测试的新手,我不知道该把这段代码放在哪里。你是不是指我应该更改mvc项目中的LogOnController?请耐心解释一下。提前致谢。 - Dilma
我希望现在对你来说已经很清楚了。如果你还有问题,请告诉我。 - Suhas
我按照给定的步骤进行了操作,遇到了一些错误,但是我成功地解决了它们。现在程序可以正常运行了。非常感谢您的帮助和支持。谢谢! - Dilma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接