I'm trying to write an MSpec test that instantiates one of my controllers with all the correct Ninject bindings. How do I go about doing that? This is what I have so far:

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

In the above code I'm simply trying to see if I can instantiate my controller with all the Ninject bindings in tact. The NinjectControllerFactory class looks like this:

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

And the DefaultModule class like this:

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

So my question is: is there a way to specify the bindings of my Ninject module in my MSpec test and then have my instantiated controller use those bindings? I want to avoid instantiating my Controller like this: var controller = new Controller() since that doesn't allow me to test the Ninject bindings. I've also looked into the TestControllerBuilder class from the MvcContrib library but I haven't figured out how to instantiate controllers with Ninject bindings with it. Thanks for the help!

有帮助吗?

解决方案

Ok I figured out how to initialize my controller along with the Ninject Bindings in my MSpec tests! Well I didn't figure it out. A coworker did but that's irrelevant now. Here is how it's done:

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

Ok that's it :). Hopefully someone else can benefit from this answer. Special thanks to my coworker for figuring this out. You know who you are :D

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top