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
}
}
Related
I am trying to unit test code that uses an API, so I am trying to decouple.
I have created an interface for the "Application" class inside the API, which is sealed.
I then created a class that uses the interface which has one method that returns an "Application" type object.
Here is where I am having trouble, in my unit test I try to create an "Application" object to verify if the return value is correct. However the "Application" class does not have any constructors, nothing public or private(I checked with reflection). The object is created by calling static Application.Connect(AnotherTypeFromAPI arg), which returns an Application object.
How do I return a fake object that I cannot create?
appMock.Connect(arg).Returns("How do I return an Application object here?"));
Or am I going about this the wrong way in regards to unit testing code that relies on an API? The entire API relies on the "Application" type so if I cannot fake it, I am not sure yet how I can stub or mock the other methods I need.
I am using C#, NUnit, NSUbstitute.
This problem can be solved but you're using the wrong pattern. Instead of exposing an instance of the Application via a new interface, you need to create an interface that fully replaces the concrete dependency.
What you have
If I understand your question correctly, you have a sealed Application class that has some methods your program needs to be able to call, and it has no public constructor, only a static factory method. Here is a simple example for discussion, with only one method, SomeMethod().
public sealed class Application
{
//private ctor prevents anyone from using new to create this
private Application()
{
}
//Here's the method we want to mock
public void SomeMethod(string input)
{
//Implementation that needs to be stubbed or mocked away for testing purposes
}
//Static factory method
static public Application GetInstance()
{
return new Application();
}
}
What you tried
What you did might look like this:
interface IApplication
{
Application Application { get; }
}
class ApplicationWrapper : IApplication
{
protected readonly Application _application;
public ApplicationWrapper()
{
_application = Application.GetInstance();
}
public Application Application
{
get { return _application; }
}
}
So that in your main code, you do this:
var a = new ApplicationWrapper();
a.Application.SomeMethod("Real argument");
That approach will never work for unit testing, because you still have a direct dependency on the sealed Application class. You've just moved it. You still need to call Application.SomeMethod(), which is a concrete method; you are supposed to depend only on the interface, not anything concrete.
What would work
In theory, the "right" way to do this is to wrap everything. So instead of exposing Application as a property, you keep it private; instead, you expose wrapped versions of the methods, like this:
public interface IApplication
{
void SomeMethod(string input);
}
public class ApplicationWrapper : IApplication
{
protected readonly Application _application;
public ApplicationWrapper()
{
_application = Application.GetInstance();
}
public void SomeMethod(string input)
{
_application.SomeMethod(input);
}
}
Then you'd call it like this:
var a = new ApplicationWrapper();
a.SomeMethod("Real argument");
Or in a full class with DI, it would look like this:
class ClassUnderTest
{
protected readonly IApplication _application; //Injected
public ClassUnderTest(IApplication application)
{
_application = application; //constructor injection
}
public void MethodUnderTest()
{
_application.SomeMethod("Real argument");
}
}
How to unit test
In your unit test, you can now mock the IApplication with a new class, e.g.
class ApplicationStub : IApplication
{
public string TestResult { get; set; } //Doesn't exist in system under test
public void SomeMethod(string input)
{
this.TestResult = input;
}
}
Notice this class has absolutely no dependency on Application. So you no longer need to call new on it, or call its factory method, at all. For unit testing purposed, you just need to ensure it gets called properly. You can do this by passing in the stub and checking the TestResult afterward:
//Arrange
var stub = new ApplicationStub();
var c = ClassUnderTest(stub);
//Act
c.MethodUnderTest("Test Argument");
//Assert
Assert.AreEqual(stub.TestResult, "Test Argument");
It's a bit more work to write the full wrapper (especially if it has a lot of methods), but you can generate a lot of that code with reflection or with third party tools. And it allows you full unit testing, which is the whole idea behind switching to that IApplication interface to begin with.
TLDR:
Instead of
IApplication wrapper = new ApplicationWrapper();
wrapper.Application.SomeMethod();
you should use
IApplication wrapper = new ApplicationWrapper();
wrapper.SomeMethod();
to remove the dependency on the concrete type.
You don't normally mock or fake static methods such as Application.Connect. Just partition the code under test so that it takes an already created IApplication object.
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.
I am using Autofac in my project,but i am unable to do a unit test on one particular class.
Consider the following Scenario :
//Class to be tested
public Class A
{
private SomeAutoFacClass B;
public void DoSomething()
{
B = scope.Resolve<ClassName>();// Resolve the object needed
// Do something with instance B
}
}
// Test class
public Class ATest
{
private A a;
[test]
public void TestMethod()
{
a.DoSomething();//*This method causes a null reference exception as it tries to resolve the objects*
}
}
In the code above,i am not able to unit test case due to the dependency injection which is only specific to that particular class.
how do i solve this? I also tried creating a autofaccontainer using Moq.
But that too fails.
The reason you are not able to test your class is because your class takes a dependency on your DI Container. This is an implementation of the Service Locator anti-pattern. It's an anti-pattern because:
the problem with Service Locator is that it hides a class' dependencies, causing run-time errors instead of compile-time errors, as well as making the code more difficult to maintain because it becomes unclear when you would be introducing a breaking change.
Instead, design your classes around
Constructor Injection in case the class is a component (a class that contains the applications behavior), where you inject the dependencies that a class directly needs through the constructor
Method Injection when the class is a data-centric object like an entity, which means the dependency is supplied to a the public method of such class, where the consuming class only uses that dependency, but not stores it.
Components are built-up by your DI Container and are registered in your Composition Root, while data-centric objects are newed up in code outside the Composition Root. In that case you need to pass along a dependency to an already constructed object.
In case you build and test a component, your code would typically look as follows:
public class ComponentA
{
private ClassName b;
public ComponentA(ClassName b)
{
this.b = b;
}
public void DoSomething()
{
// Do something with instance B
}
}
// Test class
public Class ATest
{
[test]
public void TestMethod()
{
// Arrange
B b = new FakeB();
var a = new ComponentA(b);
// Act
a.DoSomething();
// Assert
// Check whether be was invoked correctly.
}
}
In case you build and test a data-centric object that requires a dependency for one of its operations, your code would typically look as follows:
public class EntityA
{
public string Name { get; set; }
public int Age { get; set; }
public void DoSomething(ClassName b)
{
// Do something with instance B
}
}
// Test class
public Class ATest
{
[test]
public void TestMethod()
{
// Arrange
B b = new FakeB();
var a = new EntityA { Name = "Bert", Age = 56 };
// Act
a.DoSomething(b);
// Assert
// Check whether be was invoked correctly.
}
}
So to answer your initial question:
How do i unit test a class that uses IoC container classes
You don't. Your application code should not depend on the DI Container, because that leads to all kinds of complications such as being hard to test.
Using an IoC container you should aim to use IoC. Normally this is either constructor injection or property injection depending on what your container can support for auto-injection.
A pattern I use for this I call "lazy property injection" where I constructor-inject my container to act as a registry, then use the lazy resolution on property use..
What it looks like:
private readonly IoCContainer _container = null;
private IMyService _myService = null;
public IMyService MyService
{
get { return _myService ?? (_myService = _container.Resolve<IMyService>()); }
set { _myService = value; }
}
public MyClass( IoCContainer container)
{
if (container == null)
throw new ArgumentNullException("container");
_container = container;
}
Now when you go to test a method of this class, your test initializes your MyService with a Mock. When running under test, I have the IoCContainer initialized to a Mock() that throws if any .Resolve<> calls are made. This catches scenarios where your code under test might be modified to use a new dependency that hasn't been mocked out.
The benefit of this approach is that often a class will have several single-purpose methods, and by extension need a number of dependencies. In applications like web requests where maybe only one method is called, needing one dependency, the dependency resolution only retrieves the dependencies from the container that are needed, not all of them. (I.e. if you use constructor injection with 8 dependencies, all 8 need to be resolved at runtime, even if only 1 will be used.) This also simplifies unit testing to only mock out what you know will be needed rather than everything.
This question already has answers here:
Ioc/DI - Why do I have to reference all layers/assemblies in application's entry point?
(4 answers)
Closed 6 years ago.
I am trying to learn about DI, to have a better understanding of IoC, and the other benefits.
Pre DI, I have a project that has a UI project (MVC), a BusinessLogic project and a DataAccess project. I also have a SharedLib project. All projects have a reference to SharedLib. UI has a reference to BusinessLogic, and BusinessLogic has a reference to DataAccess.
I want to add the Interfaces now. So I go to my DataAccess, and add an Interface for each class, and populat them with their methods. I do the same for the business logic layer.
But in order to inject the DataAccess class, which I instantiate in the BusinessLogic class in the UI project, I need a reference to my Data project, because the UI project (correctly, I think) has no idea what an 'IDataAccess' interface is. The only fix I can see is to add a project reference in my UI to my DA project - which seems wrong.
And if I try add Unity as my container (One day in the future, once i work out how that all works), and want to initialise my Interface/Class relationships in the UI project - same issue.
Maybe the interfaces must go in some shared project? Or one project up? How should this be handled?
If you don't want the references between projects you could look into factories/abstract factories.
Your UI knows about your business layer, so you want to define a factory in your business layer which knows how to use the data layer. Then you handle all your DI in your composition root (the UI project in this example).
A simple example below using a console app as the UI, sticking to the references you stated in your question
Data layer
public interface IDataAccess
{
string GetData();
}
public class XmlDataAccess : IDataAccess
{
public string GetData()
{
return "some data";
}
}
Business layer
public interface IDataAccessFactory
{
IDataAccess GetDataAccess();
}
public class XmlDataAccessFactory : IDataAccessFactory
{
public IDataAccess GetDataAccess()
{
return new XmlDataAccess();
}
}
public class BusinessLogic
{
IDataAccessFactory dataAccessFactory;
public BusinessLogic(IDataAccessFactory dataAccessFactory)
{
this.dataAccessFactory = dataAccessFactory;
}
public void DoSomethingWithData()
{
IDataAccess dataAccess = dataAccessFactory.GetDataAccess();
Console.WriteLine(dataAccess.GetData());
}
public string GetSomeData()
{
IDataAccess dataAccess = dataAccessFactory.GetDataAccess();
return dataAccess.GetData();
}
}
UI
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IDataAccessFactory, XmlDataAccessFactory>();
var logic = container.Resolve<BusinessLogic>();
logic.DoSomethingWithData();
string useDataInUI = logic.GetSomeData();
Console.WriteLine("UI " + useDataInUI);
Console.ReadKey();
}
It's a contrived example so it looks like abstraction for nothing, but with a real world example it would make more sense.
e.g. you might have a bunch of different data access classes in your data layer database, xml files, etc. so you might define a factory for each in your business layer.
Using abstract factories
The factory could contain a lot more logic about the nitty gritty of the data layer, or as an abstract factory provide a set of individual factories to the business logic layer.
Business layer
You might instead have an abstract factory in the business layer such as
public interface IPlatformFactory
{
IDataAccessFactory GetDataAccessFactory();
IPricingFactory GetPricingFactory(); // might be in the business project, or another project referenced by it
}
with a concrete factory
public class WebPlatformFactory : IPlatformFactory
{
IDataAccessFactory GetDataAccessFactory()
{
return new XmlDataAccessFactory();
}
IPricingFactory GetPricingFactory()
{
return new WebPricingFactory(); // not shown in the example
}
}
(You might have additional concrete factories such as RetailPlatformFactory, etc.)
Your BusinessLogic class would now look something like
public class BusinessLogic
{
IPlatformFactory platformFactory;
public BusinessLogic(IPlatformFactory platformFactory)
{
this.platformFactory = platformFactory;
}
public void DoSomethingWithData()
{
IDataAccessFactory dataAccessFactory = platformFactory.GetDataAccessFactory();
IDataAccess dataAccess = dataAccessFactory.GetDataAccess();
Console.WriteLine(dataAccess.GetData());
}
public string GetSomeData()
{
IDataAccessFactory dataAccessFactory = platformFactory.GetDataAccessFactory();
IDataAccess dataAccess = dataAccessFactory.GetDataAccess();
return dataAccess.GetData();
}
}
Data layer
Your business layer no longer needs to provide an IDataAccessFactory to your UI so you can move it into your data layer in this example. So the data layer classes would be
public interface IDataAccess
{
string GetData();
}
public class XmlDataAccess : IDataAccess
{
public string GetData()
{
return "some data";
}
}
public interface IDataAccessFactory
{
IDataAccess GetDataAccess();
}
public class XmlDataAccessFactory : IDataAccessFactory
{
public IDataAccess GetDataAccess()
{
return new XmlDataAccess();
}
}
UI
Now you'd in the UI you'd configure the container and perform similar actions as
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IPlatformFactory, WebPlatformFactory>();
var logic = container.Resolve<BusinessLogic>();
logic.DoSomethingWithData();
string useDataInUI = logic.GetSomeData();
Console.WriteLine("UI " + useDataInUI);
Console.ReadKey();
}
The UI then knows nothing about the data layer/access, it's just handing off the factory creation to the business layer, which holds the data (and pricing) references.
Some recommended reading:
Composition Root
Implementing an Abstract Factory
Compose object graphs with confidence
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 {}