Reputation: 552
I am trying to mock certain methods of a class, while keeping the true implementation of other methods.
Now, I did find something related on stackoverflow here. However, none of the suggested answers help me.
Lee's answer is probably good in most cases, but it is inappropriate in my case as I really need to mock an Interface (which has various implementation) and not the class itself.
Brandon's answer is very close, but I found the following hick up.
Here is his code pasted for convenience:
var mock = new Mock<ITestClass>(); // Create Mock of interface
// Create instance of ITestClass implementation you want to use
var inst = new ActualTestClass();
// Setup to call method of an actual instance
// if method returns void use mock.Setup(...).Callback(...)
mock.Setup(m => m.SomeMethod(It.IsAny<int>())
.Returns((int x) => inst.SomeMethod(x));
What is causing me problem is that this example works for simple scenarios, but it won't work if "SomeMethod()" it to call another method from ITestClass that has a mock setup. In that case "SomeMethod()" will still use the real implementation.
For clarity:
Say ITestClass implements the methods SomeMethod and SomeOtherMethod. The former must call the latter that is mocked as per:
mock.Setup(m => m.SomeOtherMethod(It.IsAny<bool>())
.Returns(true);
Now how can this mock be used by SomeMethod instead of the real implementation?
Another reason why I need to mock an interface and not the class itself is that the latter option will not allow you to test TestClass() if it were to be a singleton.
Upvotes: 2
Views: 706
Reputation: 169
How about not using Moq at all?
You could create a wrapper class that derives from your main class and overrides the methods you want to mock with whatever you need.
Then use this derived class in your test.
Of course these overriden methods could use Moq or be defined as mocks from within this derived class.
Upvotes: 1
Reputation: 14231
Popular isolation frameworks such as Moq, NSubstitute, or FakeItEasy are constrained. Impossible solve your problem with them.
There are also unconstrained isolation frameworks: TypeMock, JustMock (both are paid) and MS Fakes (available only in VS Enterprise).
However, I recently came across an interesting free Pose library that will solve your problem.
Add package.
Open namespace:
using Pose;
Test code:
var inst = new ActualTestClass();
Shim testClassShim = Shim.Replace(() => inst.SomeOtherMethod(Is.A<bool>()))
.With((ActualTestClass _, bool b) => true);
int actual = 0;
PoseContext.Isolate(() =>
{
actual = inst.SomeMethod(1); // it will use shim inside
},
testClassShim);
Assert.Equal(0, actual);
But it is still much inferior in many ways to its commercial counterparts.
It should be noted that unconstrained tools, although they solve isolation problems extremely effectively, but in this way they forgive design errors, which can eventually lead to poor application architecture.
Upvotes: 1