2

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?

EDIT

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.

13
  • If I understand well, you want to mock a method of the same class you are testing, not a dependency inside the method, but the whole method. My question is why are you doing that? Commented Aug 18, 2020 at 16:45
  • 1
    @stackMeUp encapsulate all dependencies in their own classes, and you will not have this issue again. You decide whether you want to refactor code to support good unit testing, or resort to some kind of hack to make the tests pass. Commented Aug 18, 2020 at 18:18
  • 1
    @stackMeUp Having code in the question closer to what your actual design looks like would help with more relevant suggestions. Otherwise, as @insane_developer suggested, redesign these classes to decouple the two concerns. Using different classes/interfaces for each responsibility (SomeMethod vs SomeOtherMethod) would let you easily replace one while keeping the implementation of the other. Commented Aug 18, 2020 at 18:27
  • 1
    @stackMeUp whether you have no choice, I can't say because I don't know your application. It's possible that you don't understand how testable code is supposed to look like, for which there are plenty of resources online. Or, perhaps the application is so test-unfriendly that you can't even do the right thing without massive changes that could cause even more problems. I think you've been given clear hints here, if the former is true. Commented Aug 19, 2020 at 15:43
  • 1
    This is impossible with a constrained isolating framework such as Moq, NSubstitute, or FakeItEasy. But this is possible with unconstrained frameworks: TypeMock, JustMock, MS Fakes - all are paid. I can give you an example of a solution using the free Pose library that will allow you to do this. Commented Aug 19, 2020 at 17:15

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for that. I will check it out. Maybe I could use one of these for this specific test/issue I am having and stick to Moq for the rest. I'll mark your answer as accepted answer if nobody can suggest an alternative using Moq within the next few days.
Just wanted to mention that JustMock has a free version named JustMock Lite. The free version is comparable with Moq and you could use it for most of the tests and use the commercial version only where needed. Disclaimer: I am one of the developers behind JustMock.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.