After all what I have read about Dependency Injection and IoC I have decided to try to use Windsor Container within our application (it's a 50K LOC multi-layer web app, so I hope it's not an overkill there). I have used a simple static class for wrapping the container and I initialize it when starting the app, which works quite fine for now.
My question is about unit testing. I know that DI is going to make my life much easier there by giving me the possibility of injecting stub / mock implementations of class collaborators to the class under test. I have already written a couple of tests using this technique and it seems to make sense for me. What I am not sure about is whether I should be using IoC (in this case Windsor Castle) also in unit tests (probably somehow configure it to return stubs / mocks for my special cases) or is it better to wire-up all the dependencies manually in the tests. What do you think and what practice has worked for you ?
You don't need DI container in unit tests because dependencies are provided through mock objects generated with frameworks such as Rhino Mocks or Moq. So for example when you are testing a class that has a dependency on some interface this dependency is usually provided through constructor injection.
public class SomeClassToTest
{
private readonly ISomeDependentObject _dep;
public SomeClassToTest(ISomeDependentObject dep)
{
_dep = dep;
}
public int SomeMethodToTest()
{
return _dep.Method1() + _dep.Method2();
}
}
In your application you will use a DI framework to pass some real implementation of ISomeDependentObject in the constructor which could itself have dependencies on other objects while in a unit test you create a mock object because you only want to test this class in isolation. Example with Rhino Mocks:
[TestMethod]
public void SomeClassToTest_SomeMethodToTest()
{
// arrange
var depStub = MockRepository.CreateStub<ISomeDependentObject>();
var sut = new SomeClassToTest(depStub);
depStub.Stub(x => x.Method1()).Return(1);
depStub.Stub(x => x.Method2()).Return(2);
// act
var actual = sut.SomeMethodToTest();
// assert
Assert.AreEqual(3, actual);
}
I'm working on an ASP.NET MVC project with about 400 unit tests. I am using Ninject for dependency injection and MBUnit for testing.
Ninject is not really necessary for unit testing, but it reduces the amount of code I have to type. I only have to specify once (per project) how my interfaces should be instantiated as opposed to doing this every time I initialize the class being tested.
In order to save time on writing new tests, I have created test fixture base classes with as much generic setup code as possible. The setup procedures in those classes intialize fake repositories, create some test data and a fake identity for the test user. Unit tests only initialize data that is too specific to go into generic setup procedures.
I am also mocking objects (as opposed to faking) in some tests, but I found that faking data repositories results in less work and more accurate tests.
For example, it would be more difficult to check if the method under test I properly commits all updates to the repository after making them when using a repository mock than when I am using a repository fake.
It was quite a bit of work to set up at the beginning, but really helped me reduce save a lot of time in the long run.
I've just written a very similar style and size app. I wouldn't put any dependency injection in the unit tests because it is not complicated enough to be necessary. You should use a mocking framework to create your mocks (RhinoMocks / Moq).
Also Automocking in Moq or the Auto Mock Container in Rhinomocks will simplify building your mocks further.
Auto mocking allows you to get object
of the type you want to test without
setting up mocks by hand. All
dependencies are mocked automatically
(assuming they are interfaces) and
injected into the type constructor. If
you need to you can set up expected
behavior, but you don't have to.
As Darin has already pointed out, you don't need to use DI if you have mocks. (However, DI has a few other benefits as well, including, first of all, lessening dependencies in your code, which makes your code much easier to maintain and extend in the long run.)
I personally prefer wiring up everything in my unit tests, thus relying as little as possible on external frameworks, config files etc.
Related
I am working with TDD and all is going well. When I get to my actual Repository though I don't know how to test this.
Consider the code below - this is what I know I want to write but how do I tackle this in a test first way without doing integration testing.
public class UserDb : IUserDb
{
public void Add(User user)
{
using (var context = new EfContext())
{
context.Users.Add(user);
context.SaveChanges();
}
}
}
The link below by forsvarir is what I want to put as an answer. How I can do that?
http://romiller.com/2012/02/14/testing-with-a-fake-dbcontext/
The usual answer to these kinds of questions is:
Isolate the hard to test dependencies (the EF context)
Provide a fake implementation in your tests to verify the correct behaviour of the SUT
This all makes sense when you have interesting logic to test in your system under test. For your specific case, the repository looks like a very thin abstraction between your clean domain and EF-aware logic. Good, keep 'em that way. This also means that it's not really doing much work. I suggest that you don't bother writing isolated unit tests (wrapping EF DbContext seems like extra work that might not pull its weight).
Note that I'm not saying you shouldn't test this code: I often tend to test these thin repositories using a real database, i.e. through integrated tests. For all the code that uses these repositories however, I'd stick to isolated unit testing by providing fake repositories to the system under test. That way I have coverage on my repository code and test that EF is actually talking to my database in the correct way and all other tests that indirectly use these repositories are nice, isolated and lightning-fast.
What are you hoping to achieve by testing the 3rd party tool? You could mock out the context var fakeContext = A.Fake<IDbContext>(); and then assert that an attempt was made to write to the database. A.CallTo(() => fakeContext.SaveChanges()).MustHaveHappened();
The above example uses FakeItEasy mocking library.
How can a IoC Container be used for unit testing? Is it useful to manage mocks in a huge solution (50+ projects) using IoC? Any experiences? Any C# libraries that work well for using it in unit tests?
Generally speaking, a DI Container should not be necessary for unit testing because unit testing is all about separating responsibilities.
Consider a class that uses Constructor Injection
public MyClass(IMyDependency dep) { }
In your entire application, it may be that there's a huge dependency graph hidden behind IMyDependency, but in a unit test, you flatten it all down to a single Test Double.
You can use dynamic mocks like Moq or RhinoMocks to generate the Test Double, but it is not required.
var dep = new Mock<IMyDependency>().Object;
var sut = new MyClass(dep);
In some cases, an auto-mocking container can be nice to have, but you don't need to use the same DI Container that the production application uses.
I often use an IoC container in my tests. Granted, they are not "unit tests" in the pure sense. IMO They are more BDDish and facilitate refactoring. Tests are there to give you confidence to refactor. Poorly written tests can be like pouring cement into your code.
Consider the following:
[TestFixture]
public class ImageGalleryFixture : ContainerWiredFixture
{
[Test]
public void Should_save_image()
{
container.ConfigureMockFor<IFileRepository>()
.Setup(r => r.Create(It.IsAny<IFile>()))
.Verifiable();
AddToGallery(new RequestWithRealFile());
container.VerifyMockFor<IFileRepository>();
}
private void AddToGallery(AddBusinessImage request)
{
container.Resolve<BusinessPublisher>().Consume(request);
}
}
There are several things that happen when adding an image to the gallery. The image is resized, a thumbnail is generated, and the files are stored on AmazonS3. By using a container I can more easily isolate just the behavior I want to test, which in this case is the persisting part.
An auto-mocking container extension comes in handy when using this technique:
http://www.agileatwork.com/auto-mocking-unity-container-extension/
How can a Ioc Container be used for unit testing?
IoC will enforce programming paradigms that will make unit testing in isolation (i.e. using mocks) easier: use of interfaces, no new(), no singletons...
But using the IoC container for testing is not really a requirement, it will just provide some facilities e.g. injection of mocks but you could do it manually.
Is it useful to manage mocks in a huge solution (50+ projects) using IoC?
I'm not sure what you mean by managing mocks using IoC. Anyway, IoC containers can usually do more than just injecting mocks when it comes to testing. And if you have decent IDE support that makes refactoring possible, why not using it?
Any experience?
Yes, on a huge solution, you need more than ever a non error-prone and refactoring-adverse solution (i.e. either through a type safe IoC container or good IDE support).
Using containers with ability to resolve unregistered/uknown services like SimpleInjector, DryIoc (its mine) can return mocks for not yet implemented interfaces.
Which means that you can start development with first simple implementation and its mocked dependencies, and replace them with real thing as you progress.
I am wondering about the best way to make my system testable.
I am unsure of the best practice with DI and mocking.
If DI is facilitated by using interfaces should i build mock classes which implement the same interface as the real classes?
And then use these mock classes in my tests via DI?
I importing data into HDInsight. The data is taken from azure queues.
I want to mock/emulate both the queue and the hdinsight so my unit tests are fast and decoupled.
Should i use dependency injection in my tests or is moq sufficient, are these supposed to operate independently?
Mocks and Dependency Injection go hand in hand because without dependency injection, you would not be able to have your classes use the mocks instead of the real thing. What you don't need is a Dependency Injection Container (like Ninject for example). You can use it if you like, but if you did it right, you should be able to Unit-Test your classes by supplying all dependencies yourself.
Moq is sufficient.
Your tests use the mocks to help facilitate results. They are quick and easy to setup (once you are used to whatever mocking library you choose).
If you were to utilize a DI framework.. you would be tripling your workload. Not only are you manually stubbing out mocks.. but you are also then maintaining your DI configuration for your tests. This simply wouldn't fit nicely into any workflow.
In an MVC4 C# website, we are using Unit Testing to test our code. What we are currently doing is creating a mock database, then testing each layer:
Test the Database - connecting, initializing, load, etc.
Test the code accessing the database
Test the view layer
I want these three categories to be run in order and only if the previous one passed. Is this the right way to go about it? The old way we were doing it was using a Dependency Injection framework was a weird approach to mock testing. We actually created a mock class for each data accessor, which sucks because we have to re implement the logic of each method, and it didn't really add any value because if we made a mistake with the logic the first time, we'll make it a second.
I want these three categories to be run in order and only if the
previous one passed. Is this the right way to go about it?
No. You should be test everything in isolation and because of that any failing data access code should be completely unrelated to the view. So the view unit tests should fail for a completely different reason and because of that you should always run all tests.
In general, tests should run in isolation, and should not depend on any other tests. It seems to me that the view layer still depends on the data access code, but that you only abstracted the layer below. In that case, from the view's perspective, you are mocking an indirect dependency, which makes your unit tests more complex than strictly needed.
The old way we were doing it was using a Dependency Injection
framework was a weird approach to mock testing
I'm not sure if I get this, but it seems as if you were using the DI container inside your unit tests. This is a absolute no-no. Don't clutter your tests with any DI framework. And there's no need to. Just design your classes around the dependency injection principle (expose all dependencies as constructor arguments) and in your test you just manually new up the class under test with fake dependencies -or- when this leads to repetitive code, create a factory method in your test class that creates a new instance of the class under test.
We actually created a mock class for each data accessor, which sucks
I'm not sure, but it sounds as if there's something wrong with your design here. You would normally have a IRepository<T> interface for which you would have multiple implementations, such as a UserRepository : IRepository<User>, and OrderRepository : IRepository<Order>. In your test suite, you will have one generic FakeRespository<T> or InMemoryRepository<T> and you're done. No need to mock many classes here.
Here are two great books you should definitely read:
The Art of Unit Testing
Dependency Injection in .NET
Those books will change your life. And since you'll be reading anyway, do read this book as well (not related to your question, but code be a life changer as well).
I am just wondering if there a way I can unit test some of my controller Action in
MVC without using Repository pattern. I have develop an ASP.NET MVC site but did this without unit testing at the initial stage. Now I want to demonstrate some unit test to my tutor using may be two or more action in my controller. Most of my actions logic get data from database and one controller get data from different tables i.e actions in one controller read from different table. which I think that can be test using Generic Repository pattern. As a beginner I found that I can only unit test a code that is not coming from database but unfortunately most of the code in my controller Actions come from database. i am using the default test tool in visual Studio and EF code first approach for my database.
for example i will like to unit test only the below Actions without having to unit test other action that are in the same controller.
public ActionResult Index()
{
var model = _db.PhotoGallery;
return View(model);
}
This is just for demonstration purpose.
By definition, a unit test should only affect the method that it calls. If you can find a way to mock your _db object so that you're not actually causing a database round-trip, then you can unit test this method that relies on it. Otherwise, no.
Is your _db field's type an interface? Is it being provided via injection? If so, it's likely that you can unit test this method.
Without removing the direct dependency to the database in you controller methods you will not be able to unit test these methods.
The overall recommended way of doing this would be using an IOC Container (e.g. Ninject) in combination with MVC that allows you to pass the data you need to the constructor of your controller. That "data object" must not be tied to the database, typically it is either just a POCO object or passed as an interface.
In your unit tests you can then substitute these dependencies using an in-memory data object constructed just for your unit tests, typically "mocked" using a mocking framework (e.g. Rhino Mocks or Moq).
Using this approach you not only make your controllers unit-testable but also will end up with very loosely coupled code, a benefit that might pay off for later development.
That's what called testable code :)
When you perform unit testing, you need to be sure, that only reason of failing test is changing in SUT (system under test, or class being tested) implementation. Of course, it could be broken when dependency API changes (thats OK, you should modify SUT to use new API), but it never should fail if dependency implementations changed. Thats why mocking and stubbing used.
But if you want to mock dependency, you should not create it inside SUT. It should be injected into SUT (constructor, property of parameter injection).
So, back to your case:
if you want to have testable class, you have to inject dependency (db)
dependency should be mocked
you not forced to use Repository pattern. If you can mock your db class, just mock it. Or use any other data access abstraction