【问题标题】:asp.net mvc unit test mock issueasp.net mvc 单元测试模拟问题
【发布时间】:2011-10-04 06:05:42
【问题描述】:

在控制器中

var roles = Roles.GetAllRoles(); 

单元测试调用失败 并在

LogOnTest()(Error message is "The Role Manager feature has not been enabled.")

您能否告诉我我的测试功能是否正确或需要更多的逻辑/功能测试?

[TestMethod]
public void LogOnTest()
{
    var target = new AccountController();
    var membershipMock = MockRepository.GenerateMock<AccountMembershipService>();
    var formsMock = MockRepository.GenerateMock<IFormsAuthenticationService>();

    target.FormsService = formsMock;
    target.MembershipService = membershipMock;

    var model = new LogonModel() { USERNAME= "aa", Password = "aa"};
    string returnUrl = null;
    bool isLoginSuccess = true;
    var actual = target.LogOnFromUser(model);
    if (actual == null)
        Assert.Fail("should have redirected");
 }

控制器:

public ActionResult LogOn(LogonModel model)
        {
if(MembershipService.ValidateUser(model.UsernName, model.Password))
                {
                    FormsService.SignIn(model.UsernName, true);
                                        var roles = Roles.GetAllRoles(); //Roles got failed here
return RedirectToAction("Index", "Event");
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");

            return View("LogOn", model);
}

【问题讨论】:

  • 如果您发现一个有用的答案,您应该投票给它(点击答案左上角的向上箭头),如果它回答了您的问题,您也应该通过点击勾选标记也在答案的左上角

标签: asp.net-mvc unit-testing


【解决方案1】:

您需要围绕静态 Roles 类创建一个包装器,以便您可以注入一个您可以控制的模拟实现。基本上这可能类似于您的MembershipServiceFormsService(可能称之为IRoleService)并且需要有GetAllRoles() 方法。

您可以在控制器的 null arg 构造函数中创建默认实现(它只会委托给当前的静态类)(我想这就是您的成员资格和表单服务发生的情况,并提供一个属性以允许您像其他人一样以 smae 的方式覆盖它。

另一种选择是扩展您的会员服务以允许您调用此方法,而不是专门为角色创建另一个服务。这违反了单一职责原则,因此不一定是一个好主意,但这确实意味着您不必注入另一个依赖项,并且可以说获取成员的角色在会员服务的职权范围内。

老实说,我认为您最好将控件更改为拥有一个构造函数,该构造函数明确要求实现成员服务、表单服务和角色服务,并在测试中提供模拟。这使得控制器的依赖关系变得明确。然后,您需要采用一种新的方式来创建控制器,因为默认值只能在它们具有默认构造函数的情况下创建它们。你在这里有几个选择。要么保留你拥有的选项并使用默认值,要么实现你自己的ControllerFactory。一些细节here。我个人更喜欢ControllerFactory 方法。

【讨论】:

    【解决方案2】:

    理论上,我更喜欢@Sam 的方法,但我仍在努力让它适应我的依赖注入。我真的希望能够模拟我自己的数据并完全控制我的测试。

    不过,作为权宜之计,我在这里找到了一个建议:http://blog.gfader.com/2009/11/aspnet-how-to-show-all-roles-of-current.html

    从这里我刚刚将下面的代码添加到 App.config 中,我可以继续进行测试。

     <system.web>
          <roleManager enabled="true"
                 defaultProvider="AspNetWindowsTokenRoleProvider" />
        </system.web>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-13
      • 1970-01-01
      • 1970-01-01
      • 2014-01-14
      • 1970-01-01
      • 1970-01-01
      • 2015-05-10
      相关资源
      最近更新 更多