Why ninject gets different Db instances in nunit? - c#

I write integration tests for ASP.NET MVC based application, and I try to resolve ninject registration issue.
So for my ASP.NET MVC registration I have
kernel.Bind(typeof(ICustomDbContext), typeof(IUnitOfWork))
.ToMethod(ctx => ctx.Kernel.Get<CustomDbContext>())
.InRequestScope();
Just to clarify CustomDbContext implements IUnitOfWork and ICustomDbContext.
With that registration i guarantee that i have one unique instance per request for CustomDbContext. That registration works properly in scope of ASP.NET.
The problem is when i write integration tests.
[SetUp]
public void SetUp()
{
kernel = NinjectConfig.CreateKernel();
}
[Test]
public async Task Test()
{
// Arrange
var claaService = kernel.Get<IService>();
}
On set up step i load my composition root (which is in ASP.NET MVC project).
The problem is when i get IService (Implementation of IService.cs is Service.cs and that service has dependencies to IUnitOfWork.cs and IGenericRepository.cs. IGenericRepository.cs has dependency to ICustomDbContext).
At the end when i access IService i should have same instance of CustomDbContext (and as I said in works in scope of MVC).
I have tried to resolve it in child scope, but the result is the same (they still have different hash code):
using (var childKernel1 = new ChildKernel(kernel))
{
childKernel1.Rebind(typeof(ICustomDbContext), typeof(IUnitOfWork))
.ToMethod(ctx => ctx.Kernel.Get<CustomDbContext>())
.InThreadScope();
var claaService = childKernel1.Get<IClassService>();
}
My questions are:
Why this is happening ?
How can I resolve it (it works if i do not use ninject, but i want to find a way with Ninject, even if i have to add additional configuration in integration tests) ?

Why this is happening ?
Ninject's scoping is limited to the lifetime of the container. You have setup the container to be created for each [Test] because you are using [SetUp].
This attribute is used inside a TestFixture to provide a common set of functions that are performed just before each test method is called.
[SetUp]
public void SetUp()
{
kernel = NinjectConfig.CreateKernel();
}
If you want to use the same container across multiple tests in the same [TestFixture] (assuming this because you said "instance is not the same", but you didn't mention same as what), you need to use [OneTimeSetup] instead.
This attribute is to identify methods that are called once prior to executing any of the tests in a fixture.
[OneTimeSetUp]
public void OneTimeSetUp()
{
kernel = NinjectConfig.CreateKernel();
}
This of course assumes all of your relevant integration tests are in a single class.
In short, your Ninject container is being re-initialized on every test, which means all instances it manages are also being re-initialized.

Related

Web API global setup code, also for unit tests

Say I have some global application setup code, defined in my Global.asax, Application_Start. For example to disable certificate checking:
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
// (...)
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
// (...)
}
}
Say I also have a unit test, which depends on the code above to be run. However in my unit test, Application_Start is not called as I'm instantiating the controller directly:
var controller = new TestSubjectController();
Is there some mechanism in ASP.NET or Web API that solves this problem? What would be the best way to define the setup code, preventing duplication in my code?
Research
I've went through multiple questions on SO already. Most of them focus on unit testing Application_Start itself, however that's not the goal here. Other questions tend to look at testing using the applications external (HTTP) interface, however I'd like being able to instantiate the controller directly in my unit tests.
In addition to Batavia's suggestion you could use a [TestInitialize] attributed method or your unit testing framework of choices's equivalent to call the common static method for all tests in a certain class which would reduce the duplication you're concerned about.

Unit Testing Methods that make WCF Service Call?

First attempt at any real unit testing. I have a WPF client application which receives data from methods in a WCF service. These method calls are made directly from my view models in the client app:
public string LoadArticle()
{
MyServiceClient msc = new MyServiceClient();
return Article = msc.GetArticle(_UserName);
}
I then have a test project where I new up a viewmodel then call my method:
[TestMethod]
public void LoadArticleTestValid()
{
var articleViewModel = new ArticleViewModel("Thomas");
string userName = "Thomas";
string expected = "Article 1";
var actual = articleViewModel.LoadArticle(userName);
etc.
}
Obviously this test will fail because the client application cannot reach the service to invoke LoadArticle. How is this situation tackled? Do I use Dependency Injection and pass a IMyService interface of some kind into the constructor instead of creating MyServiceClient in the ViewModel or do I mock the service somehow?
This is the problem:
MyServiceClient msc = new MyServiceClient();
This creates a tight coupling between ArticleViewModel and MyServiceClient. In order to unit test just ArticleViewModel this dependency would need to be mocked. If there's an IMyServiceClient then you'd supply that to the class:
public ArticleViewModel
{
private IMyServiceClient ServiceClient { get; set; }
public ArticleViewModel(IMyServiceClient serviceClient)
{
this.ServiceClient = serviceClient;
}
// etc.
}
Then code within that class wouldn't create a new service client, it would just use the one that's in that property.
Then in the unit test you'd create a mock of IMyServiceClient, define expected behaviors on that mock, and supply it to the object being tested. How you do that depends on the mocking library. A quick example in Rhino Mocks might look like this:
// arrange
var serviceClient = MockRepository.GenerateMock<IMyServiceClient>();
serviceClient.Stub(c => c.GetArticle(Arg<string>.Is.Anything)).Return("Article 1");
var model = new ArticleViewModel(serviceClient);
// act
var result = model.LoadArticle("Thomas");
// assert
Assert.AreEqual("Article 1", result);
The idea here is that the unit test is only testing the LoadArticle method, not the dependencies invoked by that method. Those dependencies are supplied with expected behaviors and the result is examined based on those expected behaviors.
Note: There's nothing stopping the unit test from supplying the actual implementation of MyServiceClient as well, instead of a mock. The unit test project just needs the configuration for that service to work. (Unit test projects are application hosts, they can have App.config files.) This would be an integration test rather than a unit test, but the same assertions of the results can be made.
Yes, I think you are right I would suggest a constructor parameter of IMyService, which you can use to inject a mock into the object for testing.
Further! I would suggest not using the autogenerated service client. if you copy and paste the code out into your own class you can make it implement IMyService and effectivly hide the fact that it uses WCF, goes direct to the DB or is a mocked object from the real code.
this will allow you to inject your Mock into the WPF for UI testing

Simple Injector, can't override existing registration

I am currently using Simple Injector for the first time. In my .NET project I am running test and mocking data returned from a web service and registering the object to the container like so
_container.Register<IWebServiceOrder>(() => mock.Object, Lifestyle.Transient);
This works fine. But in my tests I want to test the behavior of the system on a second call to the web service that will contain updated data, so the mock object will need to be updated.
By default Simple Injector does not allow Overriding existing registrations but the official website states it is possible to change this behavior like below.
https://simpleinjector.readthedocs.org/en/latest/howto.html#override-existing-registrations
container.Options.AllowOverridingRegistrations = true;
Unfortunately i still get an error when i try to register the object a second time even with the above code.
The container can't be changed after the first call to GetInstance, GetAllInstances and Verify
Any ideas on why this is happening?
Replacing an existing registration after you already worked with the container hardly ever has the behavior you would expect (and this holds for all DI libraries) and that's the reason why the Simple Injector container is locked. This is described in more details here (as #qujck already pointed out).
First of all, if you are writing unit tests, you shouldn't use a container at all. Your unit tests should create the class under test themselves, or you extract this logic to a convenient factory method, such as:
private static MailNotifier CreateMailNotifier(
IDeposit deposit = null, ISendMail mailSender = null, ILog logger = null)
{
return new MailNotifier(
deposit ?? Substitute.For<IDeposit>(),
mailSender ?? Substitute.For<ISendMail>(),
logger ?? Substitute.For<ILog>());
}
This factory method is a variation to the Test Data Builder pattern.
By making use of optional parameters, it allows the unit test to specify only the fake implementation it requires during testing:
public void Notify_WithValidUser_LogsAMessage()
{
// Arrange
var user = new User();
var logger = new FakeLogger();
MailNotifier sut = CreateMailNotifier(logger: logger);
// Act
sut.Notify(user);
// Assert
Assert.AreEqual(expected: 1, actual: logger.LoggedMessages.Count);
}
If you use a container, because creating the class under test by hand is too cumbersome, it indicates a problem in your class under test (most likely a Single Responsibility Principle violation). Prevent using tools to work around problems in your design; your code is speaking to you.
For integration tests however, it is much more usual to use the container, but in that case you should simply create a new container for each integration test. This way you can add or replace the IWebServiceOrder without any problem.

Decorating specific command handlers with unit of work

I am trying to rewrite my app from a service pattern to a command and query pattern (before I move to CQRS). Currently I'm stuck on this blog.
It shows where he moved unit of work commit from the base command into a PostCommitCommandHandlerDecorator, then use Simple Injector to bind them up. The writer also stated that not all commands will require the use of unit of work, which is true in my case because not every command talks to a database but some send emails, etc.
How do I architect my commands and bindings in such a way that only those commands that are required to be wrapped in a unit of work commit will be bound as such by the IoC container?
How do I architect my commands and bindings in such a way that only those commands that are required to be wrapped in a unit of work commit will be bound as such by the IoC container?
First of all, does that really matter that not all handlers use the unit of work? Is it a problem when a unit of work is created, while it isn’t used? Because when there are no performance problems, there’s no need to make your code more complicated.
But let’s assume that it does matter. In that case, the trick is to query the container whether the unit of work is injected somewhere. You can make use of Lazy<T> to get this working. Take a look at the following registration:
Func<IUnitOfWork> uowFactory =
() => new MyUnitOfWork(connectionString);
// Register the factory as Lazy<IUnitOfWork>
container.Register<Lazy<IUnitOfWork>>(
() => new Lazy<IUnitOfWork>(uowFactory),
Lifestyle.Scoped);
// Create a registration that redirects to Lazy<IUnitOfWork>
container.Register<IUnitOfWork>(
() => container.GetInstance<Lazy<IUnitOfWork>>().Value,
Lifestyle.Scoped);
For the rest of the article I assume you're building a web application, but the idea will be the same.
With this registration, when the container resolves an object graph with a component that depends on IUnitOfWork, under the covers it will resolve the Lazy<IUnitOfWork> and get its value. We cache the Lazy<IUnitOfWork> per request, so this allows us to have another component that depends on Lazy<IUnitOfWork> and check its IsValueCreated property to see if the IUnitOfWork was injected anywhere.
Now your decorator could look like this:
public class TransactionCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> decorated;
private readonly Lazy<IUnitOfWork> lazyUnitOfWork;
public TransactionCommandHandlerDecorator(
ICommandHandler<TCommand> decorated,
Lazy<IUnitOfWork> lazyUnitOfWork)
{
this.decorated = decorated;
this.lazyUnitOfWork = lazyUnitOfWork;
}
public void Handle(TCommand command)
{
this.decorated.Handle(command);
if (this.lazyUnitOfWork.IsValueCreated)
{
this.lazyUnitOfWork.Value.SubmitChanges();
}
}
}
Note however that you still don’t know whether the unit of work is actually used or not, but I think it’s safe to assume that the unit of work will be used when it gets injected. You don’t want to inject an unused dependency.
If that doesn’t cut it, and you want to check whether it is created, you will have to inject a proxy unit of work that allows you to check this. For instance:
public class DelayedUnitOfWorkProxy : IUnitOfWork
{
private Lazy<IUnitOfWork> uow;
public DelayedUnitOfWorkProxy(Lazy<IUnitOfWork> uow)
{
this.uow = uow;
}
void IUnitOfwork.SubmitChanges()
{
this.uow.Value.SubmitChanges();
}
// TODO: Implement All other IUnitOfWork methods
}
Your configuration will now look like this:
Func<IUnitOfWork> uowFactory =
() => new MyUnitOfWork(connectionString);
// Register the factory as Lazy<IUnitOfWork>
container.Register<Lazy<IUnitOfWork>>(
() => new Lazy<IUnitOfWork>(uowFactory),
Lifestyle.Scoped);
// Register the proxy that delays the creation of the UoW
container.Register<IUnitOfWork, DelayedUnitOfWorkProxy>(
Lifestyle.Scoped);
When a command or any other dependency needs an IUnitOfWork, they will get the DelayedUnitOfWorkProxy, and it is injected with a Lazy<IUnitOfWork>. So after the object graph is created, the unit of work itself will not be created yet. Only when one of the DelayedUnitOfWorkProxy method is called, such instance is created. The decorator will stay the same.
But even this might not be good enough. It is possible that your MVC controller (assuming you are building an ASP.NET MVC application) depends on a query that uses the unit of work, but the command handler does not. In that case you probably still wouldn't want to commit the unit of work, because the command handler (or one of its dependencies) still doesn't use the unit of work.
In that case what you’re actually trying to do is to isolate the execution of command handlers in their own scope. As if they are running in a different App Domain. You want them to be independent of the web request in which they execute.
In that case you need an hybrid lifestyle. With Simple Injector you can leave all your code and configuration in tact, but switch to an hybrid lifestyle like this:
container.Options.DefaultScopedLifestyle = Lifestyle.CreateHybrid(
() => container.GetCurrentLifetimeScope() != null,
new LifetimeScopeLifestyle(),
new WebRequestLifestyle());
Func<IUnitOfWork> uowFactory =
() => new MyUnitOfWork(connectionString);
// Register the factory as Lazy<IUnitOfWork>
container.Register<Lazy<IUnitOfWork>>(
() => new Lazy<IUnitOfWork>(uowFactory),
Lifestyle.Scoped);
// Register a proxy that depends on Lazy<IUnitOfWork>
container.Register<IUnitOfWork, DelayedUnitOfWorkProxy>(
Lifestyle.Scoped);
An hybrid lifestyle is a composite of two (or more) lifestyles and it contains a predicate delegate that the container will call to check which lifestyle should be applied.
With just this configuration nothing will happen, because the LifetimeScopeLifestyle requires you to explicitly start and stop a new scope. Without a scope the container.GetCurrentLifetimeScope() method will always return null, which means that the hybrid lifestyle will always pick the WebRequestLifestyle.
What you need is to start a new lifetime scope just before you resolve a new command handler. As always, this can be done by defining a decorator:
private sealed class LifetimeScopeCommandHandlerDecorator<T>
: ICommandHandler<T>
{
private readonly Container container;
private readonly Func<ICommandHandler<T>> decorateeFactory;
public LifetimeScopeCommandHandlerDecorator(Container container,
Func<ICommandHandler<T>> decorateeFactory)
{
this.decorateeFactory = decorateeFactory;
this.container = container;
}
public void Handle(T command)
{
using (this.container.BeginLifetimeScope())
{
var decoratee = this.decorateeFactory.Invoke();
decoratee.Handle(command);
}
}
}
You should register this decorator as last decorator (outer most decorator). Instead of depending on an ICommandHandler<T> this decorator depends on an Func<ICommandHandler<T>>. This makes sure that the decorated command handler will only get resolved when the Func<T> delegate is invoked. This postpones the creation and and allows the creation of a lifetime scope first.
Since this decorator depends on two singletons (both the container and the Func<T> are singletons), the decorator itself can also be registered as singleton. This is what your configuration might look like:
// Batch register all command handlers
container.Register(
typeof(ICommandHandler<>),
typeof(ICommandHandler<>).Assembly);
// Register one or more decorators
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(TransactionCommandHandlerDecorator<>));
// The the lifetime scope decorator last (as singleton).
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(LifetimeScopeCommandHandlerDecorator<>),
Lifestyle.Singleton);
This will effectively isolate the unit of work used by commands from any unit of work that is created outside the context of a command handler within the rest of the request.
There is a simple way to achieve what you are asking. There are overloaded versions of the RegisterDecorator extension method that accept a Predicate which, in combination with a marker interface, can be used to selectively apply a decorator.
Here's an example in code:
public interface ICommandHandler<T> where T : class { }
public interface IDontUseUnitOfWork { }
public class MyCommand { }
public class MyCommandHandler :
ICommandHandler<MyCommand>, IDontUseUnitOfWork { }
public sealed class UnitOfWorkCommandDecorator<T> :
ICommandHandler<T> where T : class
{
public UnitOfWorkCommandDecorator(ICommandHandler<T> decorated) { }
}
And the registration to apply the UnitOfWorkCommandDecorator to command handlers except those that are tagged with the IDontUseUnitOfWork interface:
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(UnitOfWorkCommandDecorator<>),
x => !typeof(IDontUseUnitOfWork).IsAssignableFrom(x.ImplementationType));
This predicate feature is very useful and well worth getting to grips with.

Get the container instance for Simple Injector

I am using Simple Injector with a ASP.NET MVC project. I added the SimpleInjector.Integration.Web.Mvc nuget package. This adds SimpleInjectorInitializer class in App_Start folder and initializes the DI. The code looks something like
public static void Initialize()
{
// Did you know the container can diagnose your configuration?
// Go to: https://simpleinjector.org/diagnostics
var container = new Container();
//Container configuration code
DependencyResolver.SetResolver(
new SimpleInjectorDependencyResolver(container));
}
This configures the DI for the MVC controller correctly.
My question is, if I want to get the instance of the container in any of the controller\class to resolve some dependency manually how can I do it.
I have earlier worked on AutoFac and it has a dependency interface IComponentContext which can be injected into any class that needs to do any resolution manually.
Update:
Here is a scenario. My controller uses a service who initialization depends upon the input parameter passed in the controller method and hence the dependency cannot be instantiated during construction time.
I understand that this is somewhat an anti pattern for DI, but it is requirement at few places and hence injecting the DI container is next best thing. Simple Injector samples should use of static variable to share the container which i want to avoid and also it is not possible by the way SimpleInjectorInitializer works.
Except for any code that is part of the startup path of the application, no code should depend directly on the container (or a container abstraction, container facade, etc). This pattern is called Service Locator and Mark Seemann has a good explanation why this is a bad idea.
So components (such as Controllers) should not depend on the container directly, since this hides the used dependencies and makes classes harder to test. Furthermore your code starts to depend on an external framework (making it harder to change) or depending on an abstraction it doesn't need to know about.
My controller uses a service who initialization depends upon the input
parameter passed in the controller method and hence the dependency
cannot be instantiated during construction time
There's a general pattern for this problem: the abstract factory design pattern. The factory pattern allows you to delay the creation of types and allows you to pass in extra runtime parameters for the construction of a certain type. When you do this, your controller doesn't have to depend on Container and it prevents you from having to pass in a constructed container in your unit tests (DI frameworks should in general not be used in your unit test projects).
Do note however that letting your components require runtime data during creation is a code smell. Prevent doing that.
You might think that by doing this we are just moving the problem to the factory implementation. Although we are moving the dependency on the container into the factory implementation, we are in fact solving the problem because the factory implementation will be part of the application's Composition Root, which allows the application code itself oblivious to any DI framework.
So this is how I advice you to structure your code:
// Definition of the factory in the UI or BL layer
public interface ISomeServiceFactory
{
ISomeService Create(int inputParameter);
}
// Controller depending on that factory:
public class MyController : Controller
{
private readonly ISomeServiceFactory factory;
public MyController(ISomeServiceFactory factory)
{
this.factory = factory;
}
public ActionResult Index(int value)
{
// here we use that factory
var service = this.factory.Create(value);
}
}
In your composition root (the start up path) we define the factory implementation and the registration for it:
private class SomeServiceFactory : ISomeServiceFactory
{
private readonly Container container;
// Here we depend on Container, which is fine, since
// we're inside the composition root. The rest of the
// application knows nothing about a DI framework.
public SomeServiceFactory(Container container)
{
this.container = container;
}
public ISomeService Create(int inputParameter)
{
// Do what ever we need to do here. For instance:
if (inputParameter == 0)
return this.container.GetInstance<Service1>();
else
return this.container.GetInstance<Service2>();
}
}
public static void Initialize()
{
var container = new Container();
container.RegisterSingle<ISomeServiceFactory, SomeServiceFactory>();
}
Upon creation, the Container registers itself (using the call RegisterSingle<Container>(this)) so you can always inject the container into any component. That's similar to injecting the IComponentContext when working with Autofac. But the same holds for Autofac, Simple Injector, and any other container: you don't want to inject your container into components that are located outside the composition root (and there hardly ever is a reason for it).

Categories

Resources