chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
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!

IFaker.Instace (bad?) vs IFaker.AllInstances (good?) - (Isolate.Cleanup issue?)

+1 vote
Ran across an issue to day where our TypeMock + NUnit test are working fine within VS (running it with Resharper runner) but a few are failing on the build server (TypeMock server license).

Here\\\'s the error:

The Error: TypeMock.VerifyException :

TypeMock Verification: Method ILog.Error(Object, Exception) was expected but was not called ....

//Note: we are asserting that an Error(...) is called; which in all the TestCase scenarios it IS being called by our unit tests.


We are mocking log4net.LogManager.GetLogger(...) which is a static method and we managed to replicate the issue in our VS solution by creating a TestCase (NUNIT) for the \\\"single server-failing unit test\\\" and running it 5 times; one of the tests will always pass while the rest will FAIL.

Note: In our setup/teardown, we were using the following 3 code to cleanup our tests between runs (we even added this to our \\\"failing test\\\")


1. Isolate.CleanUp();
2. TestUtil.ResetAllStatics();            
 3. TypeMock.MockManager.ClearAll();

Analysis #1:

We looked into TypeMock \\\"Insight\\\" and notices that on the 2nd test to run we always got a StaleMock for ILog.Error... and this was the source of the problem. We noticed the call to \\\"TestUtil.ResetAllStatics()\\\" somehow called our class\\\'s constructor and creating a \\\"real instance of \\\'ILog.Error\\\'\\\" for subsequent tests; and SO, out MOCK object\\\'s Isolate.Verify call fails (since out MOCK object was not used at all....)

Isolate.Verify.WasCalledWithArguments(() => fakeILog.Error(null, null)).Matching(args => args[0].Equals(\\\".......[custom error].....);

Note: A series of set modifications were made where we got mixed results (a) once we got the same instance of \\\"fakeILog\\\" across subsequent TestCase tests, and (b) another time we got \\\"the same instance\\\" of \\\"fakeILog\\\"....

Work-Around: Finally, decided to change the Isolate.Fake.Instance to Isolate.Fake.AllInstances and this worked for us PLUS we are only using the following code for cleanup between unit test runs \\\"Isolate.CleanUp();\\\"; we dropped the other 2 calls.

Working Code:

 var fakeILog = Isolate.Fake.AllInstances<ILog>(Members.ReturnRecursiveFakes);
            Isolate.WhenCalled(() => log4net.LogManager.GetLogger((Type)null)).WillReturn(fakeILog);

Question #1:

Why is Isolate.Fake.AllInstances<ILog> and Isolate.Fake.Instance<ILog> behaving so differently?

Question #2:

What is a proper Fix for this issue? The current work-around seems a bit hacky... Maybe there is another Isolator function that we can use? The core of the problem is, if I call Isolate.Fake.Instance<x> and setup a static method to return that x, that instance \\\'x\\\' should be unique across unit tests if I call Isolate.CleanUp(); .... right?

asked Jun 26 by afuste (1,120 points)

1 Answer

0 votes

Hi Alejandro,

First, Isolator requires only the Isolate.CleanUp(); in the teardown.

You can also use the [Isolated] attribute in every test instead.

Do you have a reason for using  TestUtil.ResetAllStatics(); and TypeMock.MockManager.ClearAll();  in the cleanup?

We noticed the call to \"TestUtil.ResetAllStatics()\" somehow called our class\'s constructor and creating a \"real instance of \'ILog.Error\'\"

That\'s the defined behavior:

A #1:

Fake.AllInstances<ILog> creates an ILog handler from which you can set the behavior for all objects. Read more about it AllInstances.

Fake.Instance<ILog> creates a fake ILog \"instance\".

Without seeing the full test context I can\'t say why it failed exactly.

A #2:

I call Isolate.Fake.Instance<x> and setup a static method to return that x, that instance \'x\' should be unique across unit tests if I call Isolate.CleanUp(); .... right?

Have you tried setting up the fakes for your tests in the [SetUp] attribute? (If the tests use a common setup especially when it\'s static.)

When dealing with statics it might be safer to set it up per-test (as you are running it 5 times), since the Isolate.CleanUp cleans all the setups.

answered Jun 28 by Raphy (3,800 points)