Welcome to Typemock Answers. Here you can ask and receive answers from other community members. And if you liked or disliked an answer or thread: react with an up- or downvote Enjoy!

Faking all instances of every parent

0 votes

Hi there,

I've recently started using Typemock in an attempt to demo it at our company. I've read the documentation and have looked through at least half a dozen existing threads, but can't seem to find an answer to my exact problem.

I have a class C that derives from B, that itself derives from A. The instance of C is what I need to test and therefore needs to be real. But as C derives from B (and indirectly A), I need those two classes completely faked automatically when I create an instance of C.

See below:

class A
{
	protected int methodA()
	{
		return 1;
	}
}

class B : A
{
	protected int methodB()
	{
		return 5;
	}
}

class C : B
{
	public int methodC()
	{
		return methodA() * methodB();
	}
}

class Test
{
	public Test()
	{
		A fake_A = Isolate.Fake.AllInstances<A>(Members.ReturnRecursiveFakes, ConstructorWillBe.Ignored);
		Isolate.NonPublic.WhenCalled(fake_A, "methodA").DoInstead((MethodCallContext ctx) =>
			{
				return 2;
			}
		);
		
		B fake_B = Isolate.Fake.AllInstances<B>(Members.ReturnRecursiveFakes, ConstructorWillBe.Ignored);
		Isolate.NonPublic.WhenCalled(fake_B, "methodB").DoInstead((MethodCallContext ctx) =>
			{
				return 10;
			}
		);

		C c = new C(); // Would expect A and B to be faked automatically since I've faked all instances above. 
		int method_c_val = c.methodC(); // I get back 5, but what I need returned is 20.
	}
}

One of the threads I've already looked at is this one, but the answer in there points to an address which is no longer available:

https://www.typemock.com/answers/11613/mocking-all-instances-of-a-base-class

asked Sep 3 by Ash (160 points)
edited Sep 3 by Ash

1 Answer

0 votes

Hi Ash,

In this case, you can use:

[TestMethod]
        public void TestMethod1()
        {
            var c = new C();
            Isolate.NonPublic.WhenCalled(c, "methodA").OnBase().WillReturn(2);
            Isolate.NonPublic.WhenCalled(c, "methodB").OnBase().WillReturn(10);
            int method_c_val = c.methodC(); 
            Assert.AreEqual(20, method_c_val);
        }

You can read more about the .OnBase() feature here.

answered Sep 3 by Raphy (1,090 points)
The test also passes if you remove the OnBase feature but you can use it in cases where you have overridden virtual methods from base classes.
Regarding OnBase though, I tried it and it gave me a AmbiguousMatchException. Possibly because the method is defined in the parent as well as the gradparent with a different signature.

How would I get around this if I were to use OnBase?

I imagine this is a simplified version. Any possible solution would depend on the test itself.

Isolate fakes all overloads by default, you can to get a workaround by specifying "WithExactArguments" before WillReturn.

*In the test you sent, you are faking fake_B's methodB, but the call to methodB inside methodC is called by the C object. That's why the assert fails.

If you have an additional code example send is here or open a ticket send it to support@typemock.com.

Thanks Raphy.

I did have a look at OnBase. Unfortunately it won't suffice. The example I've described is a very simplified version of the problem I'm facing.

I'm dealing with legacy code that wasn't very well designed. An instance of C may create another instance of itself or some other class that derives from A or B; Which is why I want every instance of A and B mocked such that any instace that derives from these classes automatically see the faked properties/methods.

I'm using Isolate mostly so a non-natural solution would be ideal.
Thanks, I'll try WithExactArguments.

What about the problem of completely faking a parent without having to mock every single property/method?
Fake.AllInstances doesn't seem to fake when it comes to inheritance.

Cheers,
Ash
By design, Isolator fakes each class separately, i.e. Inherited classes aren't faked when a base class is faked.

This means that each class is to be handled separately.

We'll make it clearer in our Docs.
...