如何在我的ASP MVC MSpec测试中使用Ninject?

时间:2012-01-16 11:22:08

标签: asp.net-mvc asp.net-mvc-3 ninject mspec

我试图编写一个MSpec测试,用所有正确的Ninject绑定实例化我的一个控制器。我该怎么做呢?这就是我到目前为止所做的:

    [Subject(Concern.Initialization)]
public class when_permanent_employee_page_is_loaded_for_first_time
{
    private static PermanentEmployeeController controller;

    Establish context = () =>
        {
            NinjectControllerFactory controllerFactory = new NinjectControllerFactory();
            ControllerBuilder.Current.SetControllerFactory(controllerFactory);
            controller = (PermanentEmployeeController)controllerFactory.CreateController(new RequestContext(), "PermanentEmployee");
        };

    private Because of = () => controller.Index();

    private It should_load_all_available_jobs = () =>
        { 
            var blah = controller;
            var blah3 = 3;
        };
    It should_load_all_available_locations;
    It should_load_all_available_departments;
}

在上面的代码中,我只是试图看看我是否可以使用所有Ninject绑定来实例化我的控制器。 NinjectControllerFactory类如下所示:

public class NinjectControllerFactory : DefaultControllerFactory
{
    private IKernel kernel = new StandardKernel(new DefaultModule());

    public IKernel Kernel 
    { 
        get
        {
            return kernel;
        }
        set
        {
            this.kernel = value;
        }
    }

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            return null;
        }

        return (IController)kernel.Get(controllerType);
    }
}

DefaultModule类如下:

public class DefaultModule : NinjectModule
{
    /// <summary>
    /// Performs the binding of interfaces to their respective implementations. 'Tis very cool.
    /// </summary>
    public override void Load()
    {
        // Data service bindings
        Bind<IJobService>().To<JobServiceImpl>().InTransientScope();
        Bind<IJobWsWrapper>().To<JobWsWrapperImpl>().InTransientScope();

        // View model factory bindings
        Bind<IPermanentEmployeeViewModelFactory>().To<PermanentEmployeeViewModelFactoryImpl>().InTransientScope();
    }
}

所以我的问题是:有没有办法在我的MSpec测试中指定我的Ninject模块的绑定,然后让我的实例化控制器使用这些绑定?我想避免像这样实例化我的控制器:var controller = new Controller()因为那不允许我测试Ninject绑定。我还从MvcContrib库中查看了TestControllerBuilder类,但我还没弄明白如何使用Ninject绑定来实例化控制器。谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

好的我想出了如何在我的MSpec测试中初始化我的控制器和Ninject Bindings!好吧,我没弄清楚。一位同事做了,但现在这无关紧要。以下是它的完成方式:

    public class when_permanent_employee_page_is_loaded_for_first_time
{
    private static Mock<IJobService> jobServiceMock;
    private static Mock<IUtilsService> utilsServiceMock;
    private static PermanentEmployeeController controller;
    private static ContextMocks mocks;

    private static IList<Job> jobs = new List<Job>();
    private static IList<string> departments = new List<string>();
    private static IList<string> locations = new List<string>();
    private static PermanentEmployeeJobsViewModel viewModel;

    Establish context = () =>
        {    
            jobServiceMock = new Mock<IJobService>();
            jobServiceMock.Setup(x => x.GetJobs(1)).Returns(jobs);
            jobServiceMock.Setup(x => x.GetDepartmentsFromJobs(jobs)).Returns(departments);
            jobServiceMock.Setup(x => x.GetLocationsFromJobs(jobs)).Returns(locations);

            utilsServiceMock = new Mock<IUtilsService>();

            var kernel = new StandardKernel(new DefaultModule());
            kernel.Rebind<IJobService>().ToConstant(jobServiceMock.Object);
            kernel.Rebind<IUtilsService>().ToConstant(utilsServiceMock.Object);

            controller = kernel.Get<PermanentEmployeeController>();
            mocks = new ContextMocks(controller);
        };

    Because of = () =>
        {
            PartialViewResult view = (PartialViewResult)controller.Index();
            viewModel = (PermanentEmployeeJobsViewModel)view.ViewData.Model;
        };

    It should_load_all_available_jobs = () =>
        {
            jobServiceMock.Verify(x => x.GetJobs(1)); 
            jobServiceMock.Verify(x => x.GetDepartmentsFromJobs(jobs));
            jobServiceMock.Verify(x => x.GetLocationsFromJobs(jobs));
            viewModel.Departments.ShouldEqual(departments);
        };

    It should_load_all_available_locations;
    It should_load_all_available_departments;
}

好的就是它:)。希望其他人可以从这个答案中受益。特别感谢我的同事搞清楚这一点。你知道你是谁:D