views:

120

answers:

4

i have a something like this

public class HomeController
{
   public ActionResult Index()
   {
      var x = Container.Resolve<IOrganisationService>();
   }
}

when unit testing i get a null reference exception when the container tries to resolve
anybody knows how do to mock Container.Resolve() ?

+3  A: 

The question is, why are you resolving it in that fashion? If you instead have the dependency injected, then you can easily mock:

public class HomeController
{
    private readonly IOrganisationService organisationService;

    public HomeController(IOrganisationService organisationService)
    {
        this.organisationService = organisationService;
    }

   public ActionResult Index()
   {
      var x = this.organisationService;
   }
}

HTH,
Kent

Kent Boogaart
no, it's not like that, i just tried to simplify, i actually need it that way
Omu
@Omu: why do you need it like that?
Mauricio Scheffer
+3  A: 

You can't, because the Resolve method in question is a static method. This is one of the many reasons static types are considered evil when it comes to unit testing (and hence for general composability of code).

You seem to be applying an (anti)pattern known as Service Locator, and you are currently experiencing one of the many problems associated with it.

A better solution would be to use Constructor Injection like this:

public class HomeController
{
   private readonly IOrganisationService organisationService;

   public HomeController(IOrganisationService organisationService)
   {
       if (organisationService == null)
       {
           throw new ArgumentNullException("organisationService");
       }

       this.organisationService = organisationService;
   }

   public ActionResult Index()
   {
      var x = this.organisationService;
      // return result...
   }
}

You can now let your DI Container of choice resolve the HomeController instance from the outside. This is a much more flexible solution.

Mark Seemann
Why the downvote?
Mark Seemann
A: 

Some containers (Windsor for example) have a container which inherits from an interface. If you use this then it is implicitly mockable. If you have created a static method that you can call resolve on, then as stated above it cannot be mocked isn't advisable. If your container doesn't inherit from an interface (or the service locator pattern you are using) relies on a static method then change the implementation so it's instance based and therefore mockable.

However, I agree with the posts above. You shouldn't really need to reference your container from within your code. This couples your application to a container which is of the things you are trying to avoid by using a container.

Ian Gibson
A: 

I did it, it's like this:

//code inside the setup method
 var c = new Moq.Mock<IWindsorContainer>();
 var l = new Moq.Mock<ILookupService>();
 l.Setup(o => o.GetItems(It.IsAny<String>())).Returns(new List<LookupItem>());
 c.Setup(o => o.Resolve<ILookupService>()).Returns(l.Object);
 LocatorConfigurator.SetContainer(c.Object);
Omu
I'd really try to avoid this and use what Mark and Kent showed above.
Mauricio Scheffer