could not able to create a mock for
public MetricsProvider(IConfig configData, IMetricsLogger log)
{
config = configData;
logger = log;
oracleDAL = new OracleDataAccess(config, logger);
MetricsData = new DataCollector();
}
Steps I did:
Creatde a mock object for IConfig and IMetricsLogger.
I tried to call MetricsProvider (config , logger) but its referring Oracle connection and could not able to get connection or mock connection object.
This is actually a perfect example of why dependency injection is beneficial.
What you want is to test MetricsProvider. But because MetricsProvider internally creates an instance of OracleDataAccess and DataCollector you can't test MetricsProvider without testing those classes also.
But what do those classes depend on? Do they require additional dependencies, like app.config settings that can't be seen without looking at the source code for those classes? (And what if those classes have dependencies on other classes that have more dependencies?)
And if your test fails it will be difficult to tell if the defect is in MetricsProvider or some unknown dependency hidden in some other class.
The way to fix it is to pass an interface to the constructor which is implemented by OracleDataAccess. If it that class doesn't already implement an interface you could create a new one corresponding to the existing class. Or if you only need one method, you could define a more specific interface and wrap OracleDataAccess in a class that implements that interface.
Then MetricsProvider will depend on an interface injected into the constructor which you'll be able to mock. Since that mock will enable you to determine exactly how IOracleDataAccess behaves, now you'll be able to test MetricsProvider in isolation.
Related
I have an interface like this
public interface IConnection
{
Strategy Gc { get; }
bool IsConnected();
bool Connect();
}
I want to unit test methods of a class that uses this interface. Now I want to set Gc but it happens to be readonly. Is there a way to set Gc field without making changes to this interface class?
I am using MS fakes and Nsubstitute for unit testing. However, apparently none provides a solution. PrivateObject does not work either.
Changing Interface is not an option. Suggest better solutions.
With NSubstituteit is quite easy. First create a mock for your interface:
var mock = Substitute.For<IConnection>();
Now you can mock the member by setting any return-type for the property:
mock.Gc.Returns(Substitute.For<Strategy>());
Finally provide that mocked instance as parameter to the service depending on that instance, for example:
var target = new MyClassToTest();
target.DoSomething(mock); // mock is an instance of IConnection
Now whenever your method is called it returns a dumm-instance for Strategy. Of course you can also set any other arbitrary return-type within the Returns-statement. Just have a look at http://nsubstitute.github.io/help/set-return-value for further information.
I have a PRISM application that consists of several modules (IModule) in which the bootstrapper passes each module the DI container so that each module is able to inject/resolve services. This means that each module has its own "Composition Root" in which types are injected/resolved and I was wondering what best practices say about unit testing them.
For example, let's say I have a Resources modules which is responsible for creating and registering services that fetch data from various data sources. Let's say I implement the IModule.Initialize method as follows :
void Initialize()
{
ISomeDataService someDataService = _container.Resolve<SomeDataService>();
someDataService.Connect();
_container.RegisterInstance<ISomeDataService>(someDataService);
}
The Resources module creates an instance of SomeDataService, opens a connection, and registers it so that the other modules can use it. Note : This isn't actually how I do it, this is just for a quick illustration.
Now from a unit-testing standpoint how do I test the Initialize method? I want to test two things here :
ISomeDataService.Connect() method is being called.
IUnityContainer.RegisterInstance is being called and supplied the correct service.
Since Initialize() is in charge of actually creating concrete types and registering them, it would seem I'm out of luck when it comes to supplying it with my own ISomeDataService mock. Now it does try to Resolve the concrete type SomeDataService (which is basically the same thing as doing new SomeDataService()), so I could try to mock the concrete type SomeDataService and override the methods I want to test but this becomes a problem when the concrete type has side-effects such as the ChannelFactory which immediately upon instantiation tries to resolve for a valid WCF binding and throws an exception when it fails. I can avoid that failure by supplying it with a valid binding but I don't think a unit-test should depend on such things.
Any advice? One idea I had is as follows :
void Initialize()
{
if (_container.IsRegistered<ISomeDataService>())
{
someDataService = _container.Resolve<ISomeDataService>();
}
else
{
someDataService = _container.Resolve<SomeDataService>(); // or new SomeDataService()
}
_container.RegisterInstance<ISomeDataService>(someDataService);
someDataService.Connect();
}
Done this way I can mock ISomeDataService instead of the concrete type SomeDataService and all is well, but I don't know if this is the right approach... I'm sure I'm doing this wrong and there must be some other way.
This is an interesting question.
Looking at the example provided, there's actually three things being tested:
Initialize registers your service
ISomeDataService calls Connect
SomeDataService is properly instantiated.
Typically, I would defer Connect until some other later point as this is similar to doing work in the constructor, and it suggests that the module is doing more than one thing. If you were to remove the Connect method this would be trivial to test. But, your needs may vary, so I digress...
Each of these three things should be separate tests. The trick is finding the appropriate "seam" to decouple the instantiation from the registration and substitute the service with a mock so we can verify the Connect method.
Here's a small change to the above:
public void Initialize()
{
ISomeDataService service = DataService;
service.Connect();
_container.RegisterInstance<ISomeDataService>(service);
}
internal ISomeDataService DataService
{
get { return _service ?? _service = _container.Resolve<SomeDataService>(); }
set { _service = value;}
}
Alternatively, you can use the Subclass to Test pattern:
protected internal virtual ISomeDataService GetDataService()
{
return _container.Resolve<SomeDataService>();
}
A few interesting points from the above:
you can test registration by assigning a mock service to the subject under test, call Initialize and then attempt to resolve the service from the container manually. Assert that the resolved service is the same instance as your mock.
you can test Connect by assigning a mock, call Initialize and then verify that Connect was called.
you can test that the service can be instantiated by filling the container with the appropriate dependencies and retrieve the instance from the DataService property or the base GetDataService() (if you're using Subclass To Test).
It's the last one that is the contention point for you. You don't want to add wcf configuration for your tests. I agree, but because we have decoupled the behavior of the module in the first two tests the configuration is only needed for the last one. This last test is an integration test that proves you have the appropriate configuration file; I would mark this test with an Integration category attribute and run it with other tests that load and initialize all modules with their appropriate config. After all, the point is to verify that it all works -- the trick is to get meaningful feedback for isolated components.
One last point, the code shown in your question suggests you would test the subject by filling it with mocks. This is very similar to what I'm proposing here but the main difference is the semantic meaning: the mock is a part of the responsibilities for the subject, it is not a dependency that is injected through the container. By writing it this way it is clear what is part of the module and what is a required dependency.
Hope this helps...
it is possible in Moq Framework this?
I properly configure the container and use it but it is possible to get an concrete instance of type that was injected? For example a injected an repository to my service and I would like to get the repository instance used in service, it is possible?
_container.Configure(c =>
{
c.For<IUserApplicationService>().Use<UserApplicationService>();
c.For<IRepository<LegalEntity>>().Use<LegalEntityRepository>();
c.For<IRepository<User>>().Use<UserRepository>();
c.For<ILocalMembershipService>().Use<AspMembershipServiceAdapter>();
c.For<IEmailService>().Use(emailStub);
});
now I do it that way that i use single single object for IEmailService dependency
and what i want is to get on the fly object created. it isnt possible probably
So you want to acces your base type from your injected interface? You can always cast, but that would be against the DI principles.
Given that your container supports factories, how about setting up a factory for IEmailService in the container that creates a mock of IEmailService, stores it somewhere accessible to your tests and returns the mock.
It's often the case where I'd like to have multiple constructors in my controllers, since one of the constructors is optimal for manually injecting dependencies during unit testing and the other is optimal for using a IOC container to inject dependencies.
When using the standard service locator or DependencyResolver in MVC 3, is there any way to indicate to the controller factory which constructor to use when activating the controller?
I'd prefer not to use one of the attributes specific to an IOC framework since I want the code to remain independent of the IOC container.
UPDATE:
It seems like the majority of the answers indicate its bad practice to have multiple constructors. I don't entirely disagree with this, however, the situation arises as a result of trying to find a good solution to the mapping/conversion layer, which I asked in this question but never got a good answer to.
My code would look like this:
public class SomeController : Controller
{
private ISomeService _SomeService;
private IEntityConverter _EntityConverter;
// this would be used during unit tests when mocking the entity converter
public SomeController(ISomeService someService, IEntityConverter entityConverter)
{
_SomeService = someService;
_EntityConverter = entityConverter;
}
// this would be used when injecting via an IOC container, where it would be tedious
// to always specify the implementations for the converters
public SomeController(ISomeService someService)
: this(someService, new EntityConverter())
{
}
public ActionResult Index(SomeViewModel someViewModel)
{
if (!ModelState.IsValid)
return View(someViewModel);
else
{
ServiceInput serviceInput = _EntityConverter.ConvertToServiceInput(someViewModel);
_SomeService.DoSomething(serviceInput);
return View("Success");
}
}
}
In this very simple example, I am using an interface to do conversions between my view models and the entities that are inputs to the service layer.
I'd prefer to use an interface because this conversion can be mocked, rather than if a static method was used. However, I feel like it would be tedious to always have to specify, in the IOC container, what the implementations are for these conversion implementations, since the implementations for these conversion interfaces sit right next to the interfaces.
This may not be the best solution. I'm open to better alternatives.
Don't use multiple constructors. Your classes should have a single definition of what dependencies it needs. That definition lies in the constructor and it should therefore only have 1 public constructor.
I must say I'm not a fan of using mocking frameworks. I found that a good design of my application and my unit tests prevents me from having to use mocking frameworks all together (of course mileage may vary) .
One trick that helps me is allowing null references to be injected into the constructor by not validating the constructor arguments. This is very convenient for unit tests in cases where the class under test does not use the dependency, while in production you would still have the guarantee that null is not injected, since IOC containers will never inject null into a constructor (or at least none of the containers that I know).
Seems like a code-smell that you need an explicit constructor for testing. What if the testing ctor works but the production one doesn't? Seems like a door for bugs to creep in. It would be ideal for tests to use the same path as real clients as far as possible.
What is different between the two ?
Also if you're using some sort of attribute based DI (e.g. like MEF), I'd not be too worried about decoupling. Having an extra attribute (and the corresponding reference) should not be that big a hit... unless you foresee a change in IOC tech in the future.
Maybe I'm misreading your question, but I'm not sure why you would want to test different constructors. The tests should test what's actually going to be used.
For your tests, you ought to mock your dependencies so that they don't need an IoC container.
Using Moq:
Controller:
public SomeController(IService1 service1, IService2 service2)
{
// Do some cool stuff
}
Test Method:
[Test]
public void Some_Action_In_SomeController_Should_Do_Something()
{
var service1Mock = new Mock<IService1>();
var service2Mock = new Mock<IService2>();
var controller = new SomeController(service1Mock.Object, service2Mock.Object);
controller.Action();
// Assert stuff
}
It's all to do with your service locator, you need to configure it where you register your types.
Here is an example of using the default parameterless constructor when using Unity.
Note that by default the service locator will use the most specific constructor (the one with the most parameters)
ServiceLocator.Current.RegisterType<ICache, HttpContextCache>(new InjectionConstructor()); //use default constructor
So why did I need this? It is true I could have made a protected virtual method to resolve HttpContextBase and use extract and override in the test, or otherwise yet another interface with a method that creates the HttpContextBase that can be injected into this class.... or I could just tell unity to use the default constructor.
private readonly HttpContextBase _httpContextBase;
public HttpContextCache()
{
_httpContextBase = new HttpContextWrapper(HttpContext.Current);
}
public HttpContextCache(HttpContextBase httpContextBase)
{
_httpContextBase = httpContextBase;
}
This was a rare case and pretty much all other classes in the project have only one constructor
I've designed an application that uses the repository pattern, and then a separate service layer such as this:
public class RegistrationService: IRegistrationService
{
public void Register(User user)
{
IRepository<User> userRepository = new UserRepository();
// add user, etc
}
}
As you can see, I am instantiating my repository inside of the Register method. Now as I want to write some unit tests, I can't really get to it and replace it with a fake repository can I?
I don't want to add the repository as class variable though (and set it through a constructor) because I think that would make my code "smelly" (not all repositories are needed for all methods, and I don't need the calling layer to know about repositories etc.).
Suggestions?
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.
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.
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.
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.
You could use an IOC container and then register a different repository.
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.