测试AccountController的受保护方法

时间:2012-09-17 18:01:22

标签: asp.net-mvc unit-testing tdd nunit

我在asp.net mvc项目中测试帐户控制器。我测试了所有方法,我看了代码覆盖率结果,我注意到Initialize方法没有覆盖。

我该如何测试这种方法?

public class AccountController : Controller
{

    public IFormsAuthenticationService FormsService { get; set; }
    public IMembershipService MembershipService { get; set; }

    protected override void Initialize(RequestContext requestContext)
    {
        if (FormsService == null) { FormsService = new FormsAuthenticationService(); }
        if (MembershipService == null) { MembershipService = new AccountMembershipService(); }

        base.Initialize(requestContext);
    }

我尝试了这种测试方法,但发生了错误。

           [TestMethod]
        public void Constructor_ReturnsController()
        {
            RequestContext requestContext = new RequestContext(new MockHttpContext(), new RouteData());
            AccountController controller = new AccountController
            {
                FormsService = null,
                MembershipService = null,
                Url = new UrlHelper(requestContext),
            };

            IController cont = controller;
            cont.Execute(requestContext);
        }

错误讯息:

测试方法MVC3Project.Tests.Controllers.AccountControllerTests + AccountControllerTest.Constructor_ReturnsController抛出异常: System.NotImplementedException:未实现方法或操作。

1 个答案:

答案 0 :(得分:1)

您需要在单元测试中明确调用它:

[TestMethod]
public void AccountController_Initialize_Method_Should_WireUp_Dependencies()
{
    // arrange
    AccountController controller = new AccountController();

    // act
    controller.Initialize(null);

    // assert
    Assert.IsNotNull(controller.FormsService);
    Assert.IsNotNull(controller.MembershipService);
}

请注意,使用Initialize方法设置依赖项是不好的做法。我建议你使用依赖注入:

public class AccountController : Controller
{

    public IFormsAuthenticationService FormsService { get; private set; }
    public IMembershipService MembershipService { get; private set; }

    public AccountController(IFormsAuthenticationService formsService, IMembershipService membershipService)
    {
        FormsService = formsService;
        MembershipService = membershipService;
    }

    ... actions
}

现在,您可以设置自己喜欢的依赖注入框架,将这些依赖项注入控制器。例如,使用Ninject非常简单。安装Ninject.MVC3 NuGet,然后在生成的~/App_Start/NinjectWebCommon.cs文件中配置内核:

/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<IFormsAuthenticationService>().To<FormsAuthenticationService>();
    kernel.Bind<IMembershipService>().To<AccountMembershipService>();
}        

最后你可以将这些依赖项模拟到单元测试中,然后定义对它们的期望。