I am trying to do a simple unit test of my home controller using Moq but I'm getting an exception of
'Castle.MicroKernel.ComponentNotFoundException' occurred in Castle.Windsor.dll but was not handled in user code. No component for supporting the service OrderTrackingSystem.Core.Repositories.IRepository was found
in my HomeController on the line _repository = MvcApplication.Container.Resolve<IRepository>()
.
private IRepository _repository;
_repository = MvcApplication.Container.Resolve<IRepository>();
public HomeController(IRepository repository)
{
_repository = repository;
}
Here is my unit test code.
[TestClass]
public class HomeControllerTests
{
private Mock<IRepository> _repositoryMock;
[TestInitialize]
public void TestSetup()
{
_repositoryMock = new Mock<IRepository>();
}
[TestMethod]
public void HomeControllerIndexReturnsAView()
{
// Arrange
var controller = new HomeController(_repositoryMock.Object);
// Act
var result = controller.Index() as ViewResult;
// Assert
Assert.IsNotNull(result);
}
}
I feel like I must be missing something simple with registering or setting up the repository in my unit test. Any ideas?
I haven't used Castle Windsor, but looking at your controller, it appears to be using constructor injection to supply the controllers dependencies. This tutorial suggests that the usual way to plumb Windsor in is to create a ControllerFactory derived from DefaultControllerFactory which internally uses the Kernel to resolve the controllers dependencies. This seems to confirm that this line in your code is redundant:
_repository = MvcApplication.Container.Resolve<IRepository>();
So, your code should just be:
private IRepository _repository;
// The repository is being created + injected by Windsor.
// If this wasn't correctly wired up already, you'd be getting errors
// indicating that your HomeController didn't have a default constructor...
public HomeController(IRepository repository)
{
_repository = repository;
}
Once you're removed the call to Resolve, you should be able to inject mock dependencies into your class from your unit tests, as you have described.
Whilst there may be some instances where you might need to access the Windsor Kernel from outside your controller factory to resolve dependencies, they should be few and far between.