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.
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.