You could use an IOC container and then register a different repository.
Dependency Injection can come in really handy for these kinds of things:
public class RegistrationService: IRegistrationService
{
public void Register(User user)
{
this(user, new UserRepository());
}
public void Register(User user, IRepository<User> userRepository)
{
// add user, etc
}
}
This way you get the ability to use UserRepository as your default, and pass in a custom (Mock or Stub for testing) IRepository for whatever else you need. You may also want to change the scoping of the 2nd register method in case you don't want to expose it to everything.
An even better alternative would be to use an IoC container which would buy you syntax that is even more decoupled than the above example. You could get something like this:
public class RegistrationService: IRegistrationService
{
public void Register(User user)
{
this(user, IoC.Resolve<IRepository<User>>());
}
public void Register(User user, IRepository<User> userRepository)
{
// add user, etc
}
}
There are many IoC containers out there, as listed by other people's answers, or you could roll your own.
My suggestion would still be to move the repository to a class parameter, and use an IoC container to inject the repository when needed. This way, the code is simple and testable.
What you should be doing is using Inversion of Control or Dependency injection.
Your classes shouldn't be tied to an implementation of another class, particularly across layers like this, rather it should take the an interface representing a user repository as either a constructor, or as a property. Then when it runs, you supply the concrete implementation and it uses that. You can build fakes then that implement the repository interface and supply them at test time.
There are very many IOC containers, Unity, Ninject, Castle Windsor, and StructureMap to name a few.
I just wanted to be clear, during your unit tests, I don't know that you'd want to actually use the IOC Container. Integration tests, sure, but for the unit tests, just new up the object you are testing and provide your fake during that process. IOC containers are, at least IMO, there to help out at the application or integration testing levels, and make configuration there easier.
Your unit tests should probably stay 'pure' and just work with the objects you are trying to test. At least that's what works for me.
You need to use Dependency Injection. UserRepository is a dependency of your RegistrationService class. To make your classes properly unit testable (i.e. in isolation of their dependencies), you need to "invert" what controls your dependency creation. Currently, you have direct control, and are creating them internally. Just invert that control, and allow something external (such as an IoC container like Castle Windsor) inject them:
public class RegistrationService: IRegistrationService
{
public RegistrationService(IRepository<User> userRepo)
{
m_userRepo = userRepo;
}
private IRepository<User> m_userRepo;
public void Register(User user)
{
// add user, etc with m_userRepo
}
}
I think I forgot to add. Once you allow your dependencies to be injected, you open up the possability of them being mockable. Since your RegistrationService now takes its dependent user repository as input to its constructor, you can create a mock repository and pass that in, instead of an actual repository.
Just to add a bit of clarity (or perhaps not) to what everyone said, the way an IOC basically works is you tell it to replace X with Y. So what you would do is accept IRepository (as others have stated) as a param and then within the IOC you would tell it to replace IRepository with MockedRepository (for instance) for that specific class.
If you use an IoC that allows for web.config initialization, it makes transitioning from dev to prod very smooth. You simply modify the appropriate params within the config file and you are on your way - without needing to touch the code. Later, if you decide you want to move to a different data source - you just switch it out and you are on your way.
IoC is some fun-lovin stuff.
On a side note, you could do it without IOC injection as well if all you want to do is Unit Test. You could do this by overloading the constructor to accept an IRepository and just passing your mocked repo that way.
I'm working on something, well, almost verbatim at the moment. I'm using MOQ to mock up a proxy instance of my IUserDataRepository.
From the testing perspective:
//arrange
var mockrepository = new Mock<IUserDataRepository>();
// InsertUser method takes a MembershipUser and a string Role
mockrepository.Setup( repos => repos.InsertUser( It.IsAny<MembershipUser>(), It.IsAny<string>() ) ).AtMostOnce();
//act
var service = new UserService( mockrepository.Object );
var createResult = service.CreateUser( new MembershipUser(), "WebUser" );
//assert
Assert.AreEqual( MembershipCreateUserResult.Success, createResult );
mockrepository.VerifyAll();
MOQ can also be used to throw specific exceptions as well so that my UserService can be tested under those situations.
Then like as others have mentioned IoC will handle the required depenancies. In this case creating a real repository for the UserService class.