【问题标题】:Testing protected method of AccountController测试 AccountController 的受保护方法
【发布时间】:2012-09-17 18:01:21
【问题描述】:

我正在 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: 方法或操作未实现。

【问题讨论】:

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


    【解决方案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>();
    }        
    

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

    【讨论】:

      猜你喜欢
      • 2012-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 2013-02-04
      • 2017-05-30
      • 2014-12-24
      • 2013-10-10
      相关资源
      最近更新 更多