There are certainly many ways to stub out dependency, using constructor injection, etc etc. Here is one way to quickly stub out ServiceLocator rather than implementing ServiceLocatorStub.
Lets say you have code that uses a helper and the dependency is not quite the responsibility of that object but its the sub object that uses it. As an example the IAccessHelper uses some security server to check some values. But the AccountController doesnt use it so why inject security service in AccountController? In that case you will call a service locator to get you the AccessHelper object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class AccountController: Controller { public bool DoSomething() { var accessHelper = ServiceLocator.Current.GetInstance<IAccessHelper>(); if(accessHelper.IsValid(user)) { //do something return true; } return false; } } |
Now if you wish to unit test this you will need to do quite a few things to stub it out. The quick way to do this is using property in C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class AccountController: Controller { public boolean DoSomething() { if(AccessHelperObject.IsValid(user)) { //do something return truel } return false; } private IAccessHelper _accessHelper; public IAccessHelper AccessHelperObject { get { return _accessHelper ?? ServiceLocator.Current.GetInstance<IAccessHelper>(); } set { _accessHelper = value; } } } |
So that now when you write your unit test you dont have to care about service locator you can just stub out your IAccessHelper by just passing in a mock or stub to it.
1 2 3 4 5 6 7 8 9 10 11 |
[Test] public void Account_DoSomething() { var account = new AccoutController(); var stubAccess = MockRepository.GenerateStub<IAccessHelper>(); stubAccess.Expect(x => x.IsVaid("user")).Return(true); account.AccessHelperObject = stubAccess; var wasCalled = account.DoSomething(); Assert.That(wasCalled, Is.True); } |
This helps one to quickly break out the dependency of an object, that would otherwise take too many lines of code to test out a simple idea.
Great site! much appreciated.
Sent from my iPhone 4G
[…] requires refactoring to allow mocking of DAL (i.e. Unit-testing with Service Locator, Stubbing out ServiceLocator for unit testing) […]