I have the following interfaces and service implemented like this:
public interface IParentInterface<T> where T : class
{
T GetParent(T something);
}
public interface IChildInterface : IParentInterface<string>
{
string GetChild();
}
public class MyService
{
private readonly IChildInterface _childInterface;
public MyService(IChildInterface childInterface)
{
_childInterface = childInterface;
}
public string DoWork()
{
return _childInterface.GetParent("it works");
}
}
Here is my test for the DoWork method of MyService class:
Create a new mock object of the child interface
Setup the GetParent method of the parent interface
Pass the mock object to the service constructor
Execute the DoWork
Expect to have the resp = "It really works with something!" but it's null
[Fact]
public void Test1()
{
var mockInterface = new Mock<IChildInterface>();
mockInterface
.As<IParentInterface<string>>()
.Setup(r => r.GetParent("something"))
.Returns("It really works with something!");
var service = new MyService(mockInterface.Object);
string resp = service.DoWork(); // expects resp = "It really works with something!" but it's null
Assert.NotNull(resp);
}
Other info:
Moq 4.16.1
.NET CORE (.NET 5)
XUnit 2.4.1
Your mock setup is saying to mock the method with "something" is passed in. You should change that to match what the class is passing in, e.g. "it works" or much easier is to allow any string using It.IsAny<string>(). For example:
mockInterface
.As<IParentInterface<string>>()
.Setup(r => r.GetParent(It.IsAny<string>()))
.Returns("It really works with something!");
Related
I've classes similar to this:
public class Class1
{
private readonly IClient _client;
public Class1(Configuration config, CacheManager cacheManager)
{
_client = new Client(config, cacheManager);
}
protected async Task<T> PostAndDeserialize<T>(string param1, object param2)
{
var result = await _client.PostSomething(param1, param2);
return JsonConvert.DeserializeObject<T>(await result.Content.ReadAsStringAsync());
}
}
public class Class2 : Class1
{
public Class2(Configuration config, CacheManager cacheManager) : base(config, cacheManager)
{
}
public async Task<Response> CreateSomething(Request request)
{
//do something
var result = PostAndDeserialize<Result>("test", test);
return new Response { Id = result.Id };
}
}
I need to write unit test for Class2, CreateSomething method - how do I mock PostAndDeserialize method ? I've tried and find a way to mock protected generic class from base class but I couldn't find any help with it :( Or maybe it should be done in some other way ?(I'm new to unit test). Any help is appreciated.
I've tried using Protected() and calling method by it's name but as it's generic method it didn't work.
Your options are:
Rewrite the code so it is testable. This can be done by making the method virtual or by using composition instead of inheritance and program to an interface instead of an implementation.
Purchase Visual Studio Enterprise which includes Microsoft Fakes. Or some other third-party solution.
I have to write a unit test for an internal or private method in an abstract class in c#.
consider this:
Public Abstract Class MyAbstractClass
{
Private String MyMethod()
{
//Do Something
return "HI";
}
}
And, my test method:
public void MyTestMethod()
{
var testProcessor = new Mock<MyAbstractClass>
{
CallBase = true
};
var privateType = new PrivateType(typeof(MyAbstractClass));
PrivateObject privateObject = new PrivateObject(testProcessor , privateType);
var resValue = (String)privateObject.Invoke("MyMethod");
Assert.AreEqual(resValue ,"HI");
}
but when I run the test method, I'm getting below error:
System.Reflection.TargetException: Object does not match target type.
How to resolve that?
You should not be testing private methods:
I do not unit test private methods. A private method is an
implementation detail that should be hidden to the users of the class.
Testing private methods breaks encapsulation.
See this post for more details.
As Flydog57 says, you should be testing a derived class (not the abstract one).
You can do this easily by creating a private test class inside your test class, and use this private class in your tests.
private class MyConcreteTestClass : MyAbstractClass
{
public string SomeMethodThatCallsMethodInAbstractClass()
{
....
}
}
public void MyTestMethod()
{
// Arrange
var testProcessor = new MyConcreteTestClass();
// Act
var result = testProcessor.SomeMethodThatCallsMethodInAbstractClass();
// Asset
Assert.AreEqual(result ,"HI");
}
Assuming you are using Moq as a mocking tool, the exception shown results of passing testProcessor instead of testProcessor.Object. If you change that line to...
PrivateObject privateObject = new PrivateObject(testProcessor.Object, privateType);
...you'll get rid of this error.
This is how it should work (in NET Framework, PrivateObject and such like has not been ported to NET Core MSTest):
//productive code
public abstract class MyAbstractClass
{
private string MyMethod()
{
//Do Something
return "HI";
}
}
//testproject
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var testProcessor = new Moq.Mock<MyAbstractClass>();
var privateType = new PrivateType(typeof(MyAbstractClass));
var privateObject = new PrivateObject(testProcessor.Object, privateType);
var resValue = (string)privateObject.Invoke("MyMethod");
Assert.AreEqual(resValue, "HI");
}
}
By the way, I' didn't know a mock of an abstract class will execute the implementation of the abstract class. I thought it would create stubs that return defaults, as a mock of an interface does. Interesting feature...
You need to specify the BindingFlags to be NonPublic in order to find the private method.
I am not sure what is the PrivateObject but this should work (you may change it a little bit to make it suitable for your needs):
Type type = typeof(MyAbstractClass);
MethodInfo method = type.GetMethod(
methodName, BindingFlags.NonPublic | BindingFlags.Instance);
string result = (string)method.Invoke("MyMethod", null);
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
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.
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.