Reputation: 3600
Everyone knows that code that uses Service Locator is hard to test while Dependency Injection should be used instead.
But why Service Locator is hard to test if we can still easily mock each objects?
Consider this example (written in PHP but it could be any language)
// method we want to test that has a dependency
public myFunction() {
$someDependency = Registry::getService('Dependency');
// do something with the dependendcy
$someDependency->doSomething();
return true;
}
If we want to test this code we can simply mock our object "Dependency", example:
function testMyFunction() {
$mock = \Mockery::mock('Dependency');
$mock->shouldReceive('doSomething')->once();
Registry::set('Dependency', $mock); // set the double
$workerObject = new MyClass;
$this->assertTrue( $workerObject->myFunction() );
}
Isn't this code testable? Why Service Locator is bad in this case?
Note that we all know how bad a Service locator because it hides dependency and violets SOLID principles. But in this case i am simply referring to the testing aspect.
Upvotes: 3
Views: 418
Reputation: 233307
Everyone knows that code that uses Service Locator is hard to test while Dependency Injection should be used instead.
I didn't know that...
The reason that Service Locator is an anti-pattern isn't because it makes the code hard to test (it doesn't), but because it makes it hard to maintain.
Service Locator breaks encapsulation because you can use it from anywhere within your code, and a client has no chance of detecting this without reading through all the code that might potentially use it.
Dependency Injection is a better option, because it solves the same problems with fewer disadvantages.
Upvotes: 4
Reputation: 49673
In my experience it's mostly because it messes up with global state.
Set something in the registry in test A and someday it will mess up test B, and you will spend one whole day debugging that.
Of course if each tests completely resets everything, then you minimize the risks. But it can make your test suite slow. Again, YMMV, but for example in a big project I'm working on this is a nightmare.
Note that we all know how bad a Service locator because it hides dependency and violets SOLID principles. But in this case i am simply referring to the testing aspect.
I find it harder to test something that hides its dependencies. Having to go through all the code to know what I have to mock is boring and a waste of time.
With dependency injection I can just type new ClassToTest(_
and the IDE will show me immediately what dependencies are needed.
Upvotes: 2