I have a controller which contains a business class that internally has dependencies to a datahandler. For testing that business class I need to mock the datahandler. After setup, I am assigning the business class' datahandler with the mocked datahandler. But while debugging, the business class' datahandler is showing null , I know that I should use the constructor to inject the mocked object.But is it possible to do it without using any constructor injection ?Can any body help me with this?
my business class:
public class FooBusiness
{
public static BarDataHandler _barDatahandler = new BarDataHandler();
...
}
Test class:
public class FooBusinessTest
{
...
_mockedBarDataHandler = new Mock<IBarDataHandler>(){CallBase:true};
public FooTestMeth()
{
//Arrange
_mockedBarDataHandler.Setup(x=>x.Search(It.IsAny<int>).Returns(1);
...
FooBusiness _fooBusiness = new FooBusiness();
FooBusiness._barDatahandler = _mockedBarDataHandler.Object;
//Act
...
}
}
As I mentioned, there are multiple ways to achieve your needs.
Personally I like Shyju's answer more (Constructor Injection), but if you can't change the constructor, you can still change the implementation afterwards by setting the property:
business class:
public class FooBusiness
{
private IBarDataHandler _barDatahandler = new BarDatahandler();
public IBarDataHandler BarDatahandler
{
get { return _barDatahandler; }
set { _barDatahandler = value; }
}
public int Search(int a)
{
return _barDatahandler.Search(a);
}
}
Test class:
public class FooBusinessTest
{
_mockedBarDataHandler = new Mock<IBarDataHandler>(){CallBase:true};
public FooTestMeth()
{
//Arrange
_mockedBarDataHandler.Setup(x => x.Search(It.IsAny<int>).Returns(1);
FooBusiness fooBusiness = new FooBusiness();
fooBusiness.BarDatahandler = _mockedBarDataHandler.Object;
//Act
}
}
If you worry about to refactor the implementation, it is better to setup all the tests first. After that you can refactor with a safer feeling :)
You need to inject your dataHandler dependency to FooBusiness
You need to extract an interface for your BarDataHandler if one does not exist.
interface IBarDataHandler
{
string GetUserToken(int id);
}
public class BarDataHandler : IBarDataHandler
{
public string GetUserToken(int id)
{
// to do :read from db and return
}
}
And add a constructor to FooBusiness class which accepts an implementation of IBarDataHandler.
public class FooBusiness
{
IBarDataHandler barDataHandler;
public FooBusiness(IBarDataHandler barDataHandler)
{
this.barDataHandler=barDataHandler
}
public string GetUserToken(int id)
{
return this.barDataHandler.GetUserToken(id);
}
}
You can use any one of the dependency injection frameworks like Unity/Ninject/StructureMap to resolve your concrete implementation when your app runs.
You can use any mocking framework like Moq to mock the fake implementation of IBarDataHandler in your unittests.
Related
Usnig xUnit and Moq.
EDIT1: This approach is going to be used in a library and I want to have parameterless constructor. I do not want my application project to know about dependencies of my library
EDIT2: I just read, that this is form of property DI. I think to stick to it, if noone have any better ideas.
I am using factory pattern in my solution. For testing purposes I want to replace my factory with its mock. Below will be simplified example. In my service class constructor I am creating instance of my factory:
public class ObjectService : IObjectService
{
public ObjectService()
{
Factory = new ObjectFactory();
}
public IObjectFactory Factory { get; set; }
public IObjectModel GetObject(string firstName)
{
return Factory.GetObject(firstName);
}
}
So in unit tests I can replace instance of the factory with mock:
public class ObjectServiceTests
{
private readonly ObjectService _serv;
private readonly Mock<IObjectFactory> _factoryMock;
private readonly Mock<ISomeService> _someServMock;
private readonly string _someFirstName = "SomeFirstName";
public ObjectServiceTests()
{
_someServMock = new Mock<ISomeService>();
_someServMock.SetupGet(s => s.SecondName).Returns("Cos");
_factoryMock = new Mock<IObjectFactory>();
_factoryMock.Setup(f => f.GetObject(_someFirstName))
.Returns(new ObjectModel(_someFirstName, _someServMock.Object));
_serv = new ObjectService();
}
[Fact]
public void GetObject_Called_ReturnsObject()
{
_serv.Factory = _factoryMock.Object;
IObjectModel newObj = _serv.GetObject(_someFirstName);
Assert.Equal(_someFirstName + ", Cos", newObj.FullName);
}
}
I am wondering, is my approach with using public IObjectFactory Factory { get; set; } property correct? Because currently I have no any other idea how to do it. I will be happy for any suggestions how to replace my factory in tested method in other way.
I am trying to register different implementations of one interface and depending on the classes, which are using these implementations, certain one to be passed.
public interface ITest { }
public class Test1 : ITest { }
public class Test2 : ITest { }
public class DoSmthWhichCurrentlyNeedsTest1
{
private ITest test;
public DoSmthWhichCurrentlyNeedsTest1(ITest test)
{
this.test = test;
}
}
public class DoSmthWhichCurrentlyNeedsTest2
{
private ITest test;
public DoSmthWhichCurrentlyNeedsTest2(ITest test)
{
this.test = test;
}
}
Current solution:
services.AddTransient(x=>new DoSmthWhichCurrentlyNeedsTest1(new Test1()));
services.AddTransient(x=>new DoSmthWhichCurrentlyNeedsTest2(new Test2()));
This works well unless you have a classes with lots of dependencies, where "x.GetRequiredService" should be called for every dependency in the constructor.
What I am looking for is something like this:
services.AddTransient<ITest, Test1>
(/*If ITest is required by DoSmthWhichCurrentlyNeedsTest1*/);
services.AddTransient<ITest, Test2>
(/*If ITest is required by DoSmthWhichCurrentlyNeedsTest2*/);
Is there any other way I have missed for this purpose?
This works well unless you have a classes with lots of dependencies, where "x.GetRequiredService" should be called for every dependency in the constructor.
This is a good use-case for ActivatorUtilities.CreateInstance. Here's an example:
services.AddTransient(sp =>
ActivatorUtilities.CreateInstance<DoSmthWhichCurrentlyNeedsTest1>(sp, new Test1()));
ActivatorUtilities.CreateInstance<T> creates an instance of the type specified (DoSmthWhichCurrentlyNeedsTest1 in this example) using a combination of the DI container and any additional parameters you pass. The first argument passed in is the IServiceProvider and any additional parameters are used to provide explicit values by type.
In the example shown, ActivatorUtilities.CreateInstance will:
Look for a suitable constructor for DoSmthWhichCurrentlyNeedsTest1 and analyse its parameters.
Match anything you provide as additional parameters by assignable type against constructor parameters. We provide an instance of Test1 which is assignable to ITest, so that is used in the next step.
Create an instance of DoSmthWhichCurrentlyNeedsTest1 by matching parameters with the values you provided. For anything that you didn't provide, it attempts to resolve the values from the DI container using GetService.
This affords you the convenience of not having to worry about connecting all the DI-provided dependencies for DoSmthWhichCurrentlyNeedsTest1 while still allowing you to specify those you do care about.
Here is a working demo like below:
1.Interface:
public interface ITest {
string play();
}
2.implement class:
public class Test1 : ITest
{
public string play()
{
return "111";
}
}
public class Test2 : ITest
{
public string play()
{
return "222";
}
}
3.test class:
public class DoSmthWhichCurrentlyNeedsTest1
{
private IEnumerable<ITest> test;
public DoSmthWhichCurrentlyNeedsTest1(IEnumerable<ITest> test)
{
this.test = test;
}
public string Get()
{
var flag = test.FirstOrDefault(h => h.GetType().Name == "Test1");
var value = flag?.play();
return value;
}
}
public class DoSmthWhichCurrentlyNeedsTest2
{
private IEnumerable<ITest> test;
public DoSmthWhichCurrentlyNeedsTest2(IEnumerable<ITest> test)
{
this.test = test;
}
public string Get()
{
var flag = test.FirstOrDefault(h => h.GetType().Name == "Test2");
var value = flag?.play();
return value;
}
}
4.Startup.cs:
services.AddTransient<ITest, Test1>();
services.AddTransient<ITest, Test2>();
5.Result:
I try to create a good testable repository class to use with Moq. I don't want duplicate my selector methods (GetAll, Get, ...). My implementation works fine but SonarSource reports an error RSPEC-1699 Does anyone know of a better implementation?
var areas = new Area[] { ... };
var areaRepositoryMock = new Mock<BaseAreaRepository>() { CallBase = true };
areaRepositoryMock.Setup(m => m.Initialize()).Returns(areas);
Base Class
public abstract class BaseAreaRepository
{
protected Area[] _areas;
protected BaseAreaRepository()
{
this._areas = this.Initialize();
}
public abstract Area[] Initialize();
public Area[] GetAll()
{
return this._monitoredAreas;
}
public Area Get(int id)
{
return this._areas.FirstOrDefault(o => o.Id.Equals(id));
}
}
MyAreaRepository
public class MyAreaRepository : BaseAreaRepository
{
public override Area[] Initialize()
{
return //Load data from an other source
}
}
The RSPEC-1699 Constructors should only call non-overridable methods doens't have anything with the unit tests it will remain there regardless how you are going to test it.
Does anyone know of a better implementation?
I would like to propose another approach in order to avoid this violation and make your code even more testable.
The idea is instead of the base class use composition and DI principle.
public interface IAreaContext
{
Area[] GetAreas();
}
public class AreaRepository
{
private IAreaContext _areaContext;
protected BaseAreaRepository(IAreaContext areaContext)
{
_areaContext = areaContext;
}
public Area[] GetAll()
{
return _areaContext.GetAreas();
}
}
Then you could define multiple implementations of IAreaContext and injext:
public class MyAreaContext : IAreaContext
{
public Area[] GetAreas()
{
return //Load data from an other source
}
}
public class MyOtherAreaContext : IAreaContext
{
public Area[] GetAreas()
{
return //Load data from an other source
}
}
Now when you have this setup repository could be easily testable for different behaviors of the context itself. This is just an example to demonstrate idea:
//Arrange
var context = new Mock<IAreaContext>();
context.Setup(m => m.GetAreas()).Verifiable();
var sut = new AreaRepository(context.Object);
//Act
var _ = sut.GetAll();
//Assert
context.Verify();
If you want to test just the base class, then I would create a unit test specific implementation of the class, and just provide any helper functions to test the protected ones. Basically what you have done with MyAreaRepository but as a private class within the test class.
I wish to test a method which queries a third-party library. The library returns an object with a IReadOnlyCollection property.
There is no constructor to set the value of the property and the object has no interface for me to mock.
I have used Moq to mock the interface for the service that I call, but I can't create a mocked return value as I can't set the property.
public interface IHitService {
public Hit GetHit();
}
public class Hit {
public Hit() {
}
public IReadOnlyCollection<string> Result { get; }
}
public class TestingClass {
public void MyTest() {
Hit hit = new Hit() {
// cannot set this property
Result = new List<string>() { "hello","goodbye" };
}
Mock<IHitService> service = new Mock<IHitService>();
service.Setup(c => c.GetHit).Returns(hit);
}
}
What would be the best way for me to generate the return value to test my method? Wrapping the object with a new property to hide the base does not work.
You can use unit-test frameworks that allow you to change the behavior of a concrete object, for example in this case i used Typemock Isolator to try and solve your issue, it allows you to change the the return value of the result property so can "set" for your test without changing your code or adding extra code:
public void TestMethod1()
{
List<string> s = new List<string> { "sfas", "asfsa", "blbba" };
var hit = Isolate.Fake.NextInstance<Hit>();
Isolate.WhenCalled(() => hit.Result).WillReturnCollectionValuesOf(s);
}
In this test i mocked the Hit class and modified the return value of the Result property to a list of strings i created.
If you need to test a third-party library, it would be a better idea to create your own abstraction (interface) and rely on that for both testing and real code:
public interface IHitService
{
IHit GetHit();
}
public interface IHit
{
IReadOnlyCollection<string> Result { get; }
}
In your application code, you can create a simple wrapper class that implements IHit by delegating to the concrete third-party class. Now you can test the interface by mocking it as needed.
In general, if you can't change 3rd party code, build an adapter to it and use your own abstraction :-
public interface IHit
{
IReadOnlyCollection<string> Result { get; }
}
public interface IHitService
{
IHit GetHit();
}
public class HitAdapter : IHit
{
private Hit _hit;
public HitAdapter(Hit hit)
{
_hit = hit;
}
public IReadOnlyCollection<string> Result => _hit.Result;
}
public class TestingClass
{
public void MyTest()
{
var hitMock = new Mock<IHit>();
hitMock.Setup(c => c.Result).Returns<IReadOnlyCollection<string>>(x => new List<string>() {"hello", "goodbye"});
var service = new Mock<IHitService>();
service.Setup(c => c.GetHit()).Returns<IHit>(x => hitMock.Object);
}
}
I'm using moq.dll
When I mock a class(all the IRepository interface) i use this line code
int state = 5;
var rep = new Mock<IRepository>();
rep.Setup(x => x.SaveState(state)).Returns(true);
IRepository repository = rep.Object;
but in this case i mock all the function in repository class.
Then all the methods in class repository are substituted with the methods setup of Mock dll
I want use all the methods defined in class repository(the real class) and mock only one function(SaveState)
How can I do this? Is possible?
You can create an instance of the real repository, then use the As<>() to obtain the desired interface, which you can then override with the setup, like this:
var mockRep = new Mock<RealRepository>(ctorArg1, ctorArg2, ...)
.As<IRepository>();
mockRep.Setup(x => x.SaveState(state)).Returns(true);
Then mockRep.Object as the repository dependency to the class under test.
Note that you will only be able to Mock methods on the Interface*, or virtual methods, in this way.
Update : *This might not work in all scenarios, since .Setup will only work on virtual methods, and C# interface implementations are "virtual" and sealed by default. And using As() will prevent the partial mock behaviour.
So it appears that the RealRepository concrete class will need to implement the IRepository interface with virtual methods in order for the partial mock to succeed, in which case CallBase can be used for the wire-up.
public interface IRepo
{
string Foo();
string Bar();
}
public class RealRepo : IRepo
{
public RealRepo(string p1, string p2) {Console.WriteLine("CTOR : {0} {1}", p1, p2); }
// ** These need to be virtual in order for the partial mock Setups
public virtual string Foo() { return "RealFoo"; }
public virtual string Bar() {return "RealBar"; }
}
public class Sut
{
private readonly IRepo _repo;
public Sut(IRepo repo) { _repo = repo; }
public void DoFooBar()
{
Console.WriteLine(_repo.Foo());
Console.WriteLine(_repo.Bar());
}
}
[TestFixture]
public class SomeFixture
{
[Test]
public void SomeTest()
{
var mockRepo = new Mock<RealRepo>("1st Param", "2nd Param");
// For the partially mocked methods
mockRepo.Setup(mr => mr.Foo())
.Returns("MockedFoo");
// To wireup the concrete class.
mockRepo.CallBase = true;
var sut = new Sut(mockRepo.Object);
sut.DoFooBar();
}
}
I came to this page because I had exactly the same problem: I needed to mock a single method, which was relying on many external sources and could produce one of three outputs, while letting the rest of the class do its work. Unfortunately the partial mock approach proposed above did not work. I really don't know why it did not work. However, the main problem is that you can't debug inside such mocked class even if you put break points where you want. This is not good because you might really need to debug something.
So, I used a much simpler solution: Declare all methods that you want to mock as virtual. Then inherit from that class and write one-liner mock overrides to return what you want, for example:
public class Repository
{
/// <summary>
/// Let's say that SaveState can return true / false OR throw some exception.
/// </summary>
public virtual bool SaveState(int state)
{
// Do some complicated stuff that you don't care about but want to mock.
var result = false;
return result;
}
public void DoSomething()
{
// Do something useful here and assign a state.
var state = 0;
var result = SaveState(state);
// Do something useful with the result here.
}
}
public class MockedRepositoryWithReturnFalse : Repository
{
public override bool SaveState(int state) => false;
}
public class MockedRepositoryWithReturnTrue : Repository
{
public override bool SaveState(int state) => true;
}
public class MockedRepositoryWithThrow : Repository
{
public override bool SaveState(int state) =>
throw new InvalidOperationException("Some invalid operation...");
}
That's all. You can then use your mocked repos during unit tests AND you can debug anything you need. You can even leave the protection level below public so that not to expose what you don't want to expose.