NUnit integration tests and dependency injection

2019-02-17 22:14发布

问题:

I'm currently making use of Castle Windsor version 2.1 as my container and would like to perform integration tests using the services registered with it.

Currently, I do this my using the Common Service Locator to retrieve my service instance and perform my integration tests against it as such:

var myService = ServiceLocator.Current.GetInstance<IMyService>();
// do stuff with myService

What I'd ideally like to do is have my service dependencies injected into my NUnit test fixture automatically. Spring seems to offer this functionality, but I can't locate anything similar using Castle.

Can anyone point me in the right direction?

Edit:

I'm sure everyone has (valid) points on whether or not this is a good idea; let's just assume that it is in this scenario...Can anyone tell me how this could be accomplished using Windsor?

回答1:

If you're coming to Windsor from Spring/Spring.net you'll find that there are a number of things these projects don't agree on. This is one of them. As a Windsor advocate, I'd never use something like Spring's AbstractDependencyInjectionSpringContextTests. Injecting things into a test just seems wrong, but then again, like I said, I'm biased.

If you want to do an integration test, just create a new container instance, add whatever components you need, and run whatever you want to test, e.g:

[Test]
public void TestComponentThatDependsOnA() {
  var container = new WindsorContainer();
  container.Register(Component.For<MyComponentA>());
  container.Register(Component.For<ComponentThatDependsOnA>());
  var a = container.Resolve<ComponentThatDependsOnA>();
  var result = a.DoSomething();
  Assert.AreEqual("ok", result);
}

If you have registrations neatly wrapped in installers (as you should) you can reuse them in your tests, making tests more concise.

If you have XML config, you can easily load it with Configuration.FromXmlFile().

Also, there is no need to use Common Service Locator here.

Also useful for some integration tests is an auto-mocking container, which will automatically mock out services (unless you override them with concrete ones, of course).



回答2:

I think you can do this with Castle too. Windsor Installer is a generic interface that can be used to intialize your container/register components. You can then you can implement this interface as many times as you need depending on the context within which the application executes You can have one installer which injects real objects in a production context and another installer which injects mock objects/test doubles for integration tests.

You can find more information at http://docs.castleproject.org/Windsor.Installers.ashx