asp.net mvc单元测试模拟问题

时间:2011-10-04 06:05:43

标签: asp.net-mvc unit-testing

这里是控制器

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);
}

2 个答案:

答案 0 :(得分:1)

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

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

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

老实说,我认为你最好更改你的控件,以便有一个构造函数,它明确要求实现成员资格服务,表单服务和角色服务,并在测试中提供模拟。这使得它明确了控制器的依赖性。然后,您需要升级到创建控制器的新方法,因为默认情况下只有具有默认构造函数才能创建控制器。你在这里有几个选择。保留您拥有的选项并使用默认值,或实现您自己的ControllerFactory。一些细节here。我个人更喜欢ControllerFactory方法。

答案 1 :(得分:1)

理论上,我更喜欢@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>