Mocking an object defined in a class - c#

With the following code:
class Client {
private Service _service;
public Client() {
_service = new Service; // Connection is made to endpoint
}
public string GetData() {
return _service.ReadData();
}
}
How can Service be mocked using Moq without making modifications to the constructor or access-modifiers?

For that to be possible (or at least, cleanly done), you have to do dependency injection. Your class should not instantiate the Service. It should receive an already instantiated instance of the service.
class Client {
private Service _service;
public Client(Service service) {
_service = service; // maybe you check for null or other checks here
}
public string GetData() {
return _service.ReadData();
}
}
Next step : you should set your class to depend on an interface IService instead of on the actual Service class. This way, you can easily create another ServiceMock that can be injected instead of the Service when you instantiate your class.
class Client {
private IService _service;
public Client(IService service) {
_service = service; // maybe you check for null or other checks here
}
public string GetData() {
return _service.ReadData();
}
}
Related to your requirement :
without making modifications to the constructor or access-modifiers?
That is not a good practice, and it can get really dirty. I don't have a solution like that, given that you use the direct type and not an interface.
I don't know if you are working on some legacy code or third party library, but anticipation on this kind of problems by programming to interfaces instead of classes is the key here.

To emphasize this again:
If your new Service() constructor is connecting to the endpoint, you will not be able to mock this code. UnitTests should never depend on another endpoint being available, even if you replace the instance afterwards.
If Service does not provide a mockable Interface IService and its methods are not virtual, you will not be able to mock it at all. You would need to create a wrapper interface and implementation
A common workaround would be to create a second constructor with restricted visibility (e.g. internal) and use that to inject a mock into your class. You can control visibility by using the InternalsVisibleTo attribute. There are some discussions about creating constructors just for tests, but that is a possible first step in the right direction.
class Client {
private Service _service;
// Only for UnitTests
internal Client(Service service) {
_Service = service
}
public Client() {
_service = new Service(); // Connection is made to endpoint
}
public string GetData() {
return _service.ReadData();
}
}
Just putting together the stuff from all the comments into a usable example:
class Client {
private IService _service;
Client(IService service) {
_service = service;
}
public string GetData() {
return _service.ReadData();
}
}
class ClientFactory {
public Client CreateClient(){
var service = new Service(); // Connection is made to endpoint
return new Client(service);
}
}

Related

DryIoc: register decorator with two interfaces, retrieve the decorator instance when resolving the other interface

Here is a somewhat simplified description of the problem I'm trying to solve:
I have a service (e.g. a repository) implementing an interface that I need to inject as a dependency:
public class Service : IService { ... }
I'd like to add a decorator, for example one that add caching that also implements another interface:
public class CachingService: IService, IFlushable
{
public CachingService(IService decoratee) { ... }
public void Flush() { ... }
}
public interface IFlushable
{
public void Flush();
}
Normally, I'd just register the CachingService as an implementation of IService as as decorator, using Setup.Decorator or Setup.DecoratorWith.
But in this case I have an extra requirement related to the IFlushable interface.
There will be several different services with their own decorators, all of them implementing the both the decorated service interface and IFlushable. I need to inject all the IFlushable decorators as a dependency to be able to flush all the caches on request.
public class CacheHandler
{
public CacheHandler(IFlushable[] cache) { ... }
public void FlushAllCaches() { ... }
}
The problem is that this CacheHandler must receive the same decorator instances that were applied to the Service classes.
I have tried several solutions using RegisterMapping and tried to scope the resolution of the caches to their decorated services, but I could not make it work.
Either the I receive an error that the container cannot resolve the decorators (which makes sense) or I need to register the decorators themselves, but in the latter case the CacheHandler will receive a new set of IFlushable instances.
The more I think about the more I feel that what I'm trying to achieve here might not even by possible using a DI container. I mean maybe I'm solve this the wrong way.
My question is if my approach is valid and/or how can I get all the applied IFLushable decorator instances as a dependency.
First, I would agree with #Steven to consider inverting the control and injecting the IFlushable into the CachingService.
Second, you may realize the decorator for IService a bit differently - no need to implement it in CachingService:
[Test]
public void Answer()
{
var c = new Container();
c.Register<IService, Service>(Reuse.Singleton);
c.RegisterMany<CachingService>(Reuse.Singleton); // registers both CashingService and IFlushable with the same implementing instance
c.RegisterDelegate<CachingService, IService>(cs => cs.GetDecoratedService(), setup: Setup.Decorator);
var s = c.Resolve<IService>();
Assert.IsNotNull(s);
var cs = c.Resolve<CachingService>();
Assert.IsTrue(cs.ServiceDecorated); // check the service indeed is decorated
var f = c.Resolve<IFlushable>();
Assert.AreSame(cs, f); // check that the flushable and caching service are the same instance
}
public interface IService { }
public class Service : IService { }
// no need to implement IService for the decorator, we may use its method instead
public class CachingService : IFlushable
{
public readonly IService Service;
public bool ServiceDecorated;
public CachingService(IService service) => Service = service;
public IService GetDecoratedService()
{
ServiceDecorated = true; // do something with decorated service
return Service;
}
public void Flush() { }
}
public interface IFlushable
{
public void Flush();
}

Faking a data member that is created in the constructor

I have the following class:
public class ExampleClass
{
private readonly Service service;
public ExampleClass()
{
service = new Service();
}
private void ExecuteProcess()
{
var request = Transfer.RequestParameters;
service.SyncMethod(request);
}
}
I'm trying to fake the private readonly Service service, that is created in the constructor, because I want to ignore the call to service.SyncMethod(request).
Does anyone know how I can do this?
you can use Typemock's Isolator for faking the Service instance and for invoking the private method,for example:
[TestMethod]
public void TestMethod1()
{
Service faked = Isolate.Fake.NextInstance<Service>(Members.ReturnRecursiveFakes, ConstructorWillBe.Called);
ExampleClass exClass = new ExampleClass();
Isolate.WhenCalled(() => faked.SyncMethod(null)).IgnoreCall();
Isolate.Invoke.Method(exClass, "ExecuteProcess");
}
Provide a parameterized constructor as follows:
public ExampleClass(Service obj)
{
service = obj;
}
Then you could mock and pass the service object to the above constructor & test the function.
It is also recommended to code against an interface, in your case, create an IService, implement it in Service. Then you could inject the interface into the ExampleClass instead of the concrete implementation.
I think you should use something called 'Dependency injection'. This can be done quite easily with for example Ninject or Unity.
The result is that you do not create the service in ExampleClass, but instead pass an object of type IService to the constructor.
The interface has a method SyncMethod.
You let Service implement interface IService. You create a TestService or something that also implements IService.
In your TestService object you can make an empty implementation of the method SyncMethod to ignore it.
Your class in its current state is too tightly coupled to the dependent service, making it difficult (but not impossible) to mock dependencies to be able to test the class in isolation.
First classes should depend on abstractions and not on concretions. So abstract the Service behind an interface to allow for it to be more flexible when maintaining and testing your code in isolation.
For example
public interface IService {
void SyncMethod(RequestParameters request);
}
public class Service : IService {
//..code removed for brevity
}
Then refactor your class to follow the Explicit Dependencies Principle. This approach is known as "constructor injection".
public class ExampleClass {
private readonly IService service;
public ExampleClass(IService servic) {
this.service = service;
}
private void ExecuteProcess() {
var request = Transfer.RequestParameters;
service.SyncMethod(request);
}
}
In production, the actual dependency will be registered with the dependency container in the composition root and when the class is being resolved, the dependencies will be realized and injected into the dependent class.
This also allows for mocks/fakes/stubs to be used during testing either manually or with a mocking framework/tool of your choice.

How to deal with an IDisposable repository with Unity?

I have a job in which I have an IDisposable DbContext. I would like to unit test this job without hitting in a database. What options do i have to do this?
Im using the default Fakes assembly' of microsoft.
My job:
public void Work()
{
do
{
//code here
using (var repository = new Repository<User>())
{
repository.Save(user);
}
} while (true);
}
I'm trying to test and in this part of the test it fails because it actually creates a new instance of the Repository class.
My test Method:
using (ShimsContext.Create())
{
Data.Repository.Fakes.ShimRepository<Domain.Fakes.ShimUser>.Constructor = (a) => { };
Data.Repository.Fakes.ShimRepository<Domain.Fakes.ShimUser>.AllInstances.SaveT0 = (a, b) =>
{
};
var service = GetService();
service.Work(); //Throws exception
}
How can I fake this Save method?
You've violated DIP here, making unit testing your service far more difficult than it should be. You should also avoid generic repositories and favour role interfaces.
Instead, inject an abstraction into your service of your repository, e.g. IUsersRepository which defines your Save method. Then in your unit test of the service you can simply use a stub implementation of IUsersRepository.
Fakes tend to reveal that your code is not properly following the D in SOLID since you are creating dependencies inside your class instead of passing them in.
A much better pattern would to create an ISaveRepository interface that in turn implements IDisposable with an exposed Save() method. You should then inject an instance of your repository into your class. This will allow you to satisfy the using statement testing, as well as implement a mock that defines a .Save() method that does not hit the database.
public class Test
{
private readonly ISaveRepository _userRepository;
public Test(ISaveRepository userRepository)
{
_userRepository = userRepository;
}
public void Work()
{
using (_userRepository)
{
var cont = true;
do
{
_userRepository.Save(new User());
cont = false;
} while (cont);
}
}
}
public interface ISaveRepository : IDisposable
{
void Save<T>(T model);
}
public class Repository<T> : ISaveRepository
{
public void Dispose() { }
public void Save<TT>(TT model) {}
}
public class User {}

Best practices for IoC in complex service layer [duplicate]

This question already has answers here:
How to avoid Dependency Injection constructor madness?
(10 answers)
Closed 7 years ago.
I'm developing an MVC application, I'm using Unity for IoC. My Application basically consists of a UI layer, a services layer and a repository layer.
My typical controller is:
public class TestController : Controller
{
private ITestService testServ;
public TestController(ITestService _testServ)
{
testServ= _testServ;
}
public ActionResult Index()
{
testServ.DoSomething();
return View();
}
}
Nothing out of the ordinary, each of my controllers has a service object injected. So of my service layer objects carry out complex business rules aggregating information from many different repositories. By using IoC I'm finding my constructors look overly complex, but as the service requires access to many repositories I cannot see any way around this.
A typical class in my service layer will look like:
public class TestService : ITestService
{
private ITransactionRepository transRepo;
private IAccountRepository accountRepo;
private ISystemsRepository sysRepo;
private IScheduleRepository schRepo;
private IProfileRepository profileRepo;
public TestService(ITransactionRepository _transRepo;
IAccountRepository _accountRepo;
ISystemsRepository _sysRepo;
IScheduleRepository _schRepo;
IProfileRepository _profileRepo)
{
transRepo = _transRepo;
accountRepo = _accountRepo;
sysRepo = _sysRepo;
schRepo = _schRepo;
profileRepo = _profileRepo;
}
public DoSomething()
{
//Implement Business Logix
}
}
Several of my service layer object require 10 or more repositories. My repository sits is using Entity Framework where each repository class exposes a table in the underlying data store.
I'm looking for some advice on best practice in a situation like described.
You have created a service layer so that it acts as a facade to the underlying repositories. This approach is a good practice to provide a facade to the client with a coarse API. The clients do not have to worry about underlying repositories.
The service themselves have now a complex constructor because of the way the DI is done. The other approach is to use an abstract factory pattern at the Service layer and do a setter injection. This complexity of newing up the repositories are moved into a separate class, a factory of its own.
For example:
You may set the repositories of your test service as follows instead of a constructor
public class TestService : ITestService
{
private ITransactionRepository transRepo = DataAccess.transRepo;
private IAccountRepository accountRepo = DataAccess.accountRepo;
private ISystemsRepository sysRepo = DataAccess.sysRepo;
private IScheduleRepository schRepo = DataAccess.schRepo ;
private IProfileRepository profileRepo = DataAccess.profileRepo;
}
Below is an example of an interface for factory
public interface IRepoFactory
{
ITransactionRepository TransRepo {get;}
IAccountRepository AccountRepo {get;}
ISystemsRepository SysRepo {get;}
IScheduleRepository SchRepo {get;}
IProfileRepository ProfileRepo {get;}
}
Below is an example of a concrete factory that will new up all the repositories.
public class EfFactory : IRepoFactory
{
public ITransactionRepositry TransRepo { return new TransactionRepository();}
public IAccountRepository AccountRepo {return new AccountRepository();}
public ISystemsRepository SysRepo {return new SystemRepository();}
public IScheduleRepository SchRepo {return new SchRepository();}
public IProfileRepository ProfileRepo {return new ProfileRepository();}
}
Below is a factory method that will return the concrete factory (in your case, it would be an EF Factory)
public class RepoFactories
{
public static IRepoFactory GetFactory(string typeOfFactory)
{
return (IRepoFactory)Activator.CreateInstance(Type.GetTypetypeOfFactory)
}
}
The abstract factory with static methods to new up and return the repository objects
//Example: factoryName = MyProject.Data.EFFactory ( This can be added in your web.config or app.config)
Public static class DataAccess
{
private static readonly string DbfactoryName= ConfigurationManager.AppSettings.Get("factoryName");
private static readonly IRepoFactory factory = RepoFactories.GetFactory(DbfactoryName);
public static ITransactionRepositry transRepo
{
get {return factory.TransRepo;}
}
public static IAccountRepository accountRepo
{
get {return factory.AccountRepo;}
}
}
Here are some steps to simplify (and decrease) dependencies:
Split you service into separate services and inject them in your controller. That will decrease number of dependencies of services. The downside is that you'll need to inject more dependencies to your controllers. The next step is split controllers when they become complicated. Remember about Single Responsibility Principle.
Take a look at Bounded Context pattern: you could try to group entities that often comes together in single context and inject that context into a service instead of injecting tens of repositories:
public class TestService : ITestService
{
private readonly ITestData testData; // represents a bounded context
public TestService(ITestData testData)
{
this.testData = testData;
}
public void DoSomething()
{
this.testData.Transactions.Add(...); //It gives you access to Transactions repository
}
}

unit test a method that calls wcf service

How do I unit test a Business Layer method that makes call to WCF service?
example:
public void SendData(DataUnit dataUnit)
{
//this is WCF call
SomeServiceClient svc = new SomeServiceClient();
svc.SomeMethod(dataUnit);
}
Is there a way I can mock SomeServiceClient in my Unit test project?
Your problem here is that you have tightly coupled your Business Layer to your WCF service - you actually create a new instance of the service client within the Business Layer, meaning that it is now impossible to call the SendData method without also calling the service methods.
The best solution here is to introduce dependency injection to your architecture.
At its simplest, all you do is pass an instance of your service class into your Business Layer. This is often done at class construction time using a constructor parameter.
public class BusinessClass
{
private ISomeServiceClient _svc;
public BusinessClass(ISomeServiceClient svc)
{
_svc = svc;
}
public void SendData(DataUnit dataUnit)
{
_svc.SomeMethod(dataUnit);
}
}
Note that the code above is a design pattern, with absolutely no reliance upon any framework like an Inversion of Control container.
If it is your company's policy not to use such frameworks (an insane policy by the way), you can still manually inject your mock instances of the service inside your unit tests.
You should separate your service call from your business layer:
Using the demo below, your Business Layer method that you listed would now look like this:
public void SendData(IMyInterface myInterface, DataUnit dataUnit)
{
myInterface.SomeMethod(dataUnit);
}
Pass in a RealThing if you want to do the service call, pass in a TestThing if you just want to run a test:
public interface IMyInterface
{
void SomeMethod(DataUnit x);
}
public class RealThing : IMyInterface
{
public void SomeMethod(DataUnit x)
{
SomeServiceClient svc = new SomeServiceClient();
svc.SomeMethod(x);
}
}
public class TestThing : IMyInterface
{
public void SomeMethod(DataUnit x)
{
// do your test here
}
}

Categories

Resources