I am trying to create a NUnit test for a project that uses Ninject. The Ninject was installed via Nuget, so the Configuration clas looks similar to this simplified version:

[assembly: WebActivator.PreApplicationStartMethod(typeof(NinjectMVC3), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(NinjectMVC3), "Stop")]

public static class NinjectMVC3 
{
    private static readonly Bootstrapper Bootstrapper = new Bootstrapper();

    private static IKernel _kernel;

    public static void Start() 
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
        DynamicModuleUtility.RegisterModule(typeof(HttpApplicationInitializationModule));
        Bootstrapper.Initialize(CreateKernel);
    }

    public static void Stop()
    {
        Bootstrapper.ShutDown();
    }
}

I want those methods to be called in my startup test class. I tried:

[TestFixture]
public class TestBase
{

    [SetUp]
    public void Setup()
    {
        NinjectMVC3.Startup();
    }


    [TearDown]
    public void TearDown()
    {
        NinjectMVC3.TearDown();
    }
}

It will not work because I am trying to manually call methods that are managed by WebActivator. So I am looking for a way to instruct WebActivator to call those methods in a 'right time'. Let me remind you that there are two project that I am dealing with, one is a MVC Web Project (and it uses WebActivator for Ninject), and the other one is a Test project for my MVC Web Project. I tried to call WebActivator by changing implementation of my Setup method:

[SetUp]
public void Setup()
{
    WebActivator.ActivationManager.Run();
}

It doesn't work. As far As I understand underneath this call WebActivator should do something similar to:

foreach (var assemblyFile in Directory.GetFiles(HttpRuntime.BinDirectory, "*.dll")) {
    var assembly = Assembly.LoadFrom(assemblyFile);
    foreach (PreApplicationStartMethodAttribute preStartAttrib in assembly.GetCustomAttributes(
        typeof(PreApplicationStartMethodAttribute),
        inherit: false)) {
        preStartAttrib.InvokeMethod();
    }
}

So I guess that it is unable to find an assembly. So the question is - how can I order WebActivator to scan thru some additional assembly and fire some methods in a 'right time'. Or maybe I am mislead here, and in order to test my Ninject project I should take a different approach?

I am able to test my solutions w/o WebActivator, but because it is widely used recently, I am keen to learn how to deal with it and force it to do things that I want.

有帮助吗?

解决方案 2

Unfortunately by default WebActivator looks for a "*.dll" in a c:\tmp... directory, and due to that it is unable to find project libriaries that are included to the solution.

I ended up geting the source code and adding a following code to the ActivationManager class:

public static void AddAssembly(Assembly assembly)
{
    if (_assemblies == null)
    {
        _assemblies = new List<Assembly>();
    }
    _assemblies.Add(assembly);
}

And in test class:

 private const int PreStartInitStage_DuringPreStartInit = 1;
    [SetUp]
    public void Setup(){
        WebActivator.ActivationManager.AddAssembly(Assembly.GetAssembly(typeof(NinjectMVC3)));
        typeof(BuildManager).GetProperty("PreStartInitStage", BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, PreStartInitStage_DuringPreStartInit, null);
        WebActivator.ActivationManager.RunPreStartMethods();
        Kernel = NinjectMVC3.GetKernel();
    }

This is ugly code, and I hope to see one day a better approach.

其他提示

I would avoid using WebActivator from your test project as it will not play well outside of asp.net.

If you want to test the setup of your Ninject kernel than i would make the CreateKernel() method public and call that from your Setup() method.

public static IKernel CreateKernel()

...

[SetUp]
public void Setup()
{
    NinjectMVC3.CreateKernel();
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top