I have a service (AccountService) which has around eight methods. One of these methods sends an email. I have another service (EmailService) which is constructor injected into the AccountService.
I was wondering whether it's necessary to do this because it feels like every time I add functionality with a dependency to a method I have to change all my tests where I'm mocking up the dependencies for the constructor. This feels like DI is actually making it harder to change things, rather than easier.
So I was thinking about using the DependencyResolver in my controller action which calls the AccountService to get hold of the EmailService and pass it in. However, will this affect my tests?
How would I go about testing the controller action that used the dependency resolver? Given that the account service is constructor injected by ninject into the AccountController.
Cheers.
Don't use the DependencyResolver in your Controller! Just use it to create the controller using Ninject (See https://github.com/ninject/ninject.web.mvc/wiki). Everything else should be created by Ninject using constructor injection.
Actually, Unit Testing with proper DI and a design that follows the SOLID principles is quite easy.
In the test fixture setup you do nothing else than creating a (dynamic) mock for each dependency and an instance of the object under test using the created mocks as dependencies. That way you have to call the constructor exactly once for all your tests for each class.
If testing is hard it's not because of DI but rather by either not following the SOLID principles (most likely the single responsibility principle) or because of bad tests e.g. Unittests that use real instances of dependencies rather than mocks or doing too much in your test fixture setup.
Have you considered using the Property DI or is it necessary to inject it into the .ctor?
BTW:for your tests are you using somekind of Mocking Framework (e.g. Moq, RhinoMocks)?
Hope it will help you.
Related
I have a web app with several REST API controllers. This controllers got injected repositories as per this tutorial using SimpleInjector. I'd like to add some end-to-end testing to my project to make sure controller's method calls affect database in predictable manner (I'm using EF6, MySQL, code first). I was going to use this plan to test my app. I like overall approach but it seems like in this approach author is feeding db context directly into controller. In my case I have a Controller that gets an injected Repository from constructor and in turn Repositiry gets injected DbContext. Obviously I can hardcode the chain of creating DbContext, instantiating Repository followed by instantiating a Controller but it kinda defies the purpose of using the SimpleInjector, isn't it? I think there should be the way do it in more transparrent manner.
Basically I would like to inject separate database into my tests. When server is running it's using one database, when tests are running they are using the other ad-hoc database.
I have my test classes in a separate project, so I will need a way to instantiate my Controllers and Repositories from the main project. I'm not sure how I can do it either. Is it a good idea to expose my SimpleInjector.Container from another project somehow?
Additional info: I'm using .Net Framework (non-Core), I would like to manage withouth mocking for now unless it's required.
You can abstract the DbContext behind an interface and use SimpleInjector's option to override registrations for your tests. That will allow you to register a different implementation of your context for testing. Then in your test setup code call your standarad registrations, assuming they're all in your composition root and/or bootstrapping projedct. Then flip the override switch and register the test context.
Override Registrations
- For testing only
In your case, I would expect you to don't have to do anything in particular. Your end-to-end tests would call into a test version of the web application over HTTP, and this test application is configured with a connection string that points at a test database. This way you can use the exact same DI configuration, without having to do any changes. You certainly don't want to inject a different DbContext during testing.
Another option is to test in-memory, which means you don't call the web application over HTTP, but instead request a controller directly from Simple Injector and call its methods. Here the same holds: the only thing you want to change is your connection string, which is something that should already be configurable.
When using IoC for dependency injection the most recommended use is constructor injection (as told by many articles), my question is :
Is it better to inject using the constructor parameters or passing the IoC container through the constructor to inject the classes needed, and what is more useful for unit testing ?
Although passing the container through the constructor is better than making the container accessible as a singleton for the complete application, it is still a form of Service Locator (anti-pattern), and is not recommended. This has clear disadvantages:
It makes your code much harder to follow.
It makes it much less obvious when the Single Responsibility Principle is violated (since the class hides which things it depends on).
It makes it much hard to test, since you need to pass a configured container and you need to look in the code to see what the test need.
When requesting instances from the container directly from within every class, you will disable many features that IOC containers give you, because you don't allow the container to build up the object graph. Depending on the framework of choice, certain lifestyles and features like context based injection will not be usable.
All your tests use a container instance, making your tests come complex, and all your test have a dependency on the DI framework, which makes it very expensive to switch to another framework when needed.
Just inject the dependencies into the constructor, never* the container itself.
*Exception to this rule is when such class is located inside the appliation's Composition Root. In that case it's not considered to be the Simple Locator pattern, because that class is simply an infrastructure component.
Using constructor/property injection is better. When you pass the IOC container to the constructor you are no longer doing dependency injection and inversion of control. You are doing the Service Locator pattern. This means that classes no longer get their dependencies injected by the consumer, but they try are trying to fetch them. You are also probably tying your code to some particular DI framework.
I have a a fairly significant dependency graph for an object I want to test. What is the easiest way to resolve my dependencies without having to register mocks everywhere?
For example, I have a dependency graph like this:
PublicApi
ApiService
AccountingFacade
BillingService
BillingValidation
BillingRepository
UserService
UserRepository
I want to test PublicApi.CreateUser(), and I want it to run through all the code, but I want to mock the repositories so I don't have to write anything to the database. Should I just use a DI container and register all my services, replacing the repositories with mocks, then resolve PublicApi and run the method?
I was looking into AutoFixture, and it looks like it might be able to handle something like this, but I can't quite wrap my head around the whole 'Freeze' vs 'Register' and it's integration with Moq.
For Unittests you should only mock the direct dependencies. In your case you create PublicApi and inject a mock for ApiService and verify if PublicApi is calling the appropriate methods with the correct values on the ApiService Mock.
The same way you test all the other components isolated from the deeper dependencies.
If you want to test the combination of several components, that isn't unit testing but rather integration testing. Therefore it depends of how you are putting your classes together. e.g. if you are using an IoC container, it probably supports replacing the configuration for the repositories in some way. In this case you can use the configuration of the application and replace the repositories and potentially also the views with mocks.
This may not be helpful in the least but I will say it anyway.
It seems you are trying to test too much at once, why not just test BillingService -> BillingValidation, then BillingService -> BillingRepository etc. This way you would have a suite of tests proving that each one works, then when you are up at the PublicApi Layer you only need to mock ApiService, as you have already tested everything beneath it, so there is no value in testing it again.
Generally I will only test 1 layer at a time, but I dont know your full scenario so you may have something which I am not accounting for, so if this is the case and you REALLY need to test all of this together I would just bring in a simple and lightweight DI framework like Ninject or something.
This way you can just bind all your types to mocks, then instanciate your PublicApi from it.
With ninject it would look something like:
Kernel.Bind<UserRepository>.ToConst(YourMockUserRepositoryInstance);
Kernel.Bind<UserService>.ToConst(YourMockUserServiceInstance);
Kernel.Bind<BillingRepository>.ToConst(YourMockBillingRepositoryInstance);
Kernel.Bind<BillingValidation>.ToConst(YourMockBillingValidationInstance);
Kernel.Bind<BillingService>.ToConst(YourMockBillingServiceInstance);
Kernel.Bind<AccountingFacade>.ToConst(YourMockAccountingFacadeInstance);
Kernel.Bind<ApiService>.ToConst(YourMockApiServiceInstance);
Kernel.Bind<PublicApi>.ToSelf();
var publicApi = Kernel.Get<PublicApi>();
Although you have to ask yourself, what are you testing here? if its just interactions I would do as I first mention, if its more then maybe think about the latter choice. Either way I hope it gives you some options.
I'm building an ASP MVC 3 application in which I use Unity as IOC container and I register it on the DependencyResolver. In my controller I can then do this:
DependencyResolver.Current.GetService(GetType(IViewAllPersonsHandler))
Then when I write my unit tests I redefine my mappings in my test to use mocked objects.
A colleague of mine told me that doing this is considered as an Anti Pattern.
Can anyone tell me whether this is the case and why?
I know that normally I should inject my dependencies in the constructor, but as my controller grows the constructors parameters get lengthy.
Thx
Most folks consider the service locator pattern an anti-pattern. Probably since one can get around it with some leg-work.
If you are doing it to limit the constructor parameters you could try something different. I use property injection. Since I use castle windsor the container injects public properties by default. Last I looked Unity did not do this and you had to use some extension to get that to work.
Other than that you could split your controller or delegate to tasks within your actions.
But I would also stay away from service locator from within you controller.
HTH
You can use System.Web.Mvc.DependencyResolver.SetResolver(resovlveDependencyMock);
It's easy with Moq:
DependencyResolver.SetResolver(Mock.Of<IServiceLocator>(s => s.GetInstance(It.IsAny<Type>()) == cacheMock.Object));
(C#, WCF Service, Rhino Mocks, MbUNit)
I have been writing tests for code already in place (yes I know its the wrong way around but that's how its worked out on my current contract). I've done quite a bit of re-factoring to support mocking - injecting dependencies, adding additional interfaces etc - all of which have improved the design. Generally my testing experience has been going well (exposing fragility and improving decoupling). For any object I have been creating the dependant mocks and this sits well with me and makes sense.
The app essentially has 4 physical layers. The database, a repository layer for data access, a WCF service that is connected to the repository via a management (or business logic) layer, so top down it looks like this;
WCF
Managers
Repository
Database
Testing the managers and repository layer has been simple enough, mocking the dependencies with Rhino Mocks and injecting them into the layer under test as such.
My problem is in testing the top WCF layer. As my service doesn't have the constructor to allow me inject the dependencies, I'm not sure how I go about mocking a dependency when testing the public methods (ServiceContracts) on the service.
I hope that's made sense and any help greatly appreciated. I am aware of TypeMockIsolator etc, but really don't want to go down that route both for budget and other reasons I won't go into here. Besides I'm sure there are plenty of clever 'Stackers' who have the info I need.
Thanks in advance.
Is there a specific reason you cant have a constructor on your service?
If not, you can have overloaded constructors with a default constructor wiring up the defaults and one parametrized constructor with your dependencies. You can now test the parametrized ctor and rely on the default ctor for creating the instance in production.
public MyService() : this(new DefaultDep1(), new DefaultDep2())
{
}
public MyService(IDep1 d1, IDep2 d2)
{
}
A better solution if you use dependency injection would be to use the WCF IInstanceProvider interface to create your service instance and provide the needed dependencies via that injection point. An example using Structure Map can be found here.
You could make the WCF services a thin layer over the 'managers', so they have little or no logic in them which needs testing. Then don't test them and just test the managers. Alternatively, you could achieve a similar effect by having another 'service' layer which contains the logic from the services, which can be tested, and make the actual WCF code just pass through to that.
Our WCF service gets all its dependencies from a Factory object, and we give the service a constructor which takes IFactory. So if we want to write a test which mocks one of the dependencies, say an IDependency, we only need to inject a mock factory, which is programmed to give mocked IDependency object back to the service.
If your using an inversion of control (IoC), such as Unity, AutoFac or Castle Windsor, and a mocking framework (eg. Moq, NMock, RhinoMocks) this is simple enough as long as you have the right design.
For a good tutorial on how to do it with RhinoMock and Windsor, take a look at this blog article - http://ayende.com/Blog/archive/2007/02/10/WCF-Mocking-and-IoC-Oh-MY.aspx
If you're using Castle Windsor, take a look at the WCF facility, it lets you use non-default constructor and inject dependencies into your services, among other things.