How to mock method which is called from another method - c#

Lets say I have this
public interface ISomeInterface
{
public string GetSomething();
}
public class Sample : ISomeInterface
{
public string GetSomething()
{
return "HELLO";
}
public string MethodToTest()
{
return GetSomething();
}
}
I need to mock
GetSomething()
in order to change string output of
MethodToTest()
So I did this:
var mockClientConfigExtensions = new Mock<ISomeInterface>();
mockClientConfigExtensions.Setup(ss => ss.GetSomething()).Returns("DDDD");
var _os = new Sample();
var k = _os.MethodToTest();
Assert.Equal("DDDD", k);
The problem is
GetSomething()
still returns HELLO instead of mocking it.
How do I mock GetSomething(); ?

Your mocked interface with the Setup is mockClientConfigExtensions, but the instance you are testing, k, is a concrete type and completely different to the one you performed a Setup on.
This is not how you should be mocking. Usually you would mock dependencies of the class under test and then perform setups on those.
If you really must mock the class under test, then you need to actually setup the methods on a concrete instance not on the interface. You also need to make the methods you want to mock virtual. e.g:
public class Sample : ISomeInterface
{
public virtual string GetSomething()
{
return "HELLO";
}
public string MethodToTest()
{
return GetSomething();
}
}
...
var mockSample = new Mock<Sample>();
mockSample.Setup(s => s.GetSomething()).Returns("mystring");
Assert.Equal("mystring", mockSample.Object.MethodToTest());
https://github.com/Moq/moq4/wiki/Quickstart

Related

How to register dependencies based on the class they are required from(using built-in IOC-container in ASP CORE)

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:

Abstract class constructor call overridable method

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.

Is it possible to mock a method with using of Activator.CreateInstance()?

My method has a type parameter, so I am trying in my unit test to define a mock object and pass a type of it with a hope, that the instance of this type will mock the method as I have defined it. But if I call a method of my mock after I have created it with Activator.CreateInstance(), I become NotImplementedException.
Is it possible to mock a method with using of Activator.CreateInstance()?
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
[TestClass]
public class MyTestClass
{
[TestMethod]
public void TestDoFunc()
{
var vmod = new MyViewModel();
var mock = new Mock<IAmAnInterface<MyViewModel>>();
mock.Setup(x => x.DoInterfaceFunc(vmod)).Callback<MyViewModel>((viewModel) => { viewModel.Created = true; }).Returns(true);
Assert.IsTrue(mock.Object.DoInterfaceFunc<MyViewModel>(vmod));//this works
Assert.IsTrue(vmod.Created);//this works
var mockObjFromActivator = Activator.CreateInstance(mock.Object.GetType()) as IAmAnInterface<MyViewModel>;
Assert.IsTrue(mockObjFromActivator.DoInterfaceFunc<MyViewModel>(vmod));//this throw NotImplementedException
}
}
public class MyViewModel { public bool Created { get; set; } }
public interface IAmAnInterface<TViewModel> { bool DoInterfaceFunc<TViewModel>(TViewModel vmod); }
EDIT:
I want to test such function:
void DoFunc(Type objType)
{
var vmod = new MyViewModel();
var objImplInterface = Activator.CreateInstance(objType) as IAmAnInterface<MyViewModel>;
objImplInterface.DoInterfaceFunc(vmod);
if (vmod.Created)
{
//more logic...
}
}
When I read your code I assume you want to test your IAmAnInterface interface. However you can only test a class which is an implementation of the interface because it contains code which describes what your method should do.
I would recommend your to write your test from scratch with the following in mind: use mocking when their are dependencies in your class or method which you are testing. Because it could be hard to manipulate the depended class for example to return an error, mocking those will make it easier to test various situations which can occur in your method.
I hope the example below would make it more clear.
Let say we have 2 classes with each their own interface:
public interface IFoo {
string DoFuncX();
}
public class Foo : IFoo
{
IBar _bar;
public Foo(IBar bar) {
_bar = bar;
}
public string DoFuncX() {
try {
return _bar.DoFuncY();
} catch (Exception ex) {
return "ERROR";
}
}
}
public interface IBar {
string DoFuncY();
}
public class Bar : IBar {
public string DoFuncY() {
return "bar";
}
}
and I want to test DoFuncX in class Foo and I expect that it enters in catch when _bar.DoFunctY throws an error:
Test__Foo_DoFuncX__IBar_Throws_Error() {
// Arrange
var mockedIBar = Mock<IBar>();
mockedIBar.Setup(b => b.DoFuncY()).throw(new Exception("Mocked IBar Throws Errors"));
// Act
var foo = new Foo(mockedIBar);
var result = foo.DoFuncX();
// Assert
Assert.Equal(result, "ERROR");
}
code can contains errors, but I think it makes clear what it should do.
You need to get rid of the CreateInstance call. The obvious thing to do is to have DoFunc be passed a factory method instead or/as well as the Type (if it can't be passed the instance to use directly):
void DoFunc(Func<IAmAnInterface<MyViewModel>> factory)
{
var vmod = new MyViewModel();
var objImplInterface = factory();
objImplInterface.DoInterfaceFunc(vmod);
if (vmod.Created)
{
//more logic...
}
}
Of course, you may be able to arrange for the factory to be supplied via other means, or for the instance to use to be injected by a dependency injection system.
This may mean changes, in turn, for how whatever contains DoFunc has to be created.
E.g. you may instead have a factory passed to the constructor that implements Func<Type, IAmAnInterface<MyViewModel> and you then later use that in DoFunc, and of course provide a mock during testing that hands back the mocked interface.

How to assign a mocked object to a object in controller?

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.

moq only one method in a class

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.

Categories