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 Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
I am writing some tests using the full verson of Isolator 5.2.x on a Sharepoint webpart tha requires me to mock out SPFarm.Local, the static property that allows you to grab the list of all services in the farm.

I setup the mock as follows at the start of each isolated test

 private static void   SetupFakeFarm()
{
   SPFarm fakeFarm = Isolate.Fake.Instance<SPFarm>(Members.ReturnRecursiveFakes);

   List<SPService> fakeServiceCollection = new List<SPService>{Isolate.Fake.Instance<SPWebService>  (Members.ReturnRecursiveFakes)};
   // some more items created......

  Isolate.Swap.NextInstance<SPFarm>().With(fakeFarm);
  Isolate.WhenCalled(() => fakeFarm.Services).WillReturnCollectionValuesOf(fakeServiceCollection);

   // setup some more when called
}


I can then us these fakes to run tests against

[TestMethod, Isolated]
public void MyTest() {
   SetupFakeFarm();
   SPFarm localFarm = SPFarm.Local;

   // Get all the services from the farm object
   foreach (SPService service in localFarm.Services)
   { ....}

    // some asserts
}



If I run each of my tests individually then they work perfectly, but if I run them as batch (via VS Test tools or TestDriven.NET) the first one works but the subsequent ones fail as the localFarm returned does not appear to be the fake.

Is there something special I need to do to dispose of fakes of statics between tests other than setting the lsolate attribute?
asked by rfennell (6.8k points)

4 Answers

0 votes
Hi,

According to the code you posted, you seem to be misusing SwapNextInstance - SwapNextInstance replaces objects instantiated in the code under test, while SPFarm.Local is a static call. You only need to set
Isolate.Swap.NextInstance<SPFarm>().With(fakeFarm); 


With this:
Isolate.WhenCalled(() => SPFarm.Local).WillReturn(fakeFarm);


I quickly ran your code locally and that seemed to help; please let me know if this works on your end.
Thanks,
Doron
Typemock Support
answered by doron (17.2k points)
0 votes
Doron

Thanks that fixed the problem.

It does raise a question in my mind as I am trying to get a clear picture of when to use one form of fake over another:

As I have the Isolate attribute set on each test I thought that whole Typemock system was reset for each test so....

As there is only one call to SPFarm.Local in the code per test why is the Swap.NextInstance() not equivalent to the WhenCalled() ?

They both work for single tests, but not the batch so is my assumption that the Isolate attribute resets everything incorrect?


Thanks

Richard
answered by rfennell (6.8k points)
0 votes
Richard,

You are right in that the Isolate attribute resets fake behavior between each and every test. However, SwapNextInstance<T> is triggered if and only if a constructor for T has been called. It is not equivalent to WhenCalled() but rather complementing.

Generally speaking, you set behaviors on your fake object (or static methods) using WhenCalled() and then you can choose how to inject that fake behavior to the code under test:
- If the code under test receives a reference to the fake behavior, you just pass it in.
- If the code under tests receives it from a third party, you fake that third party to return the fake object you set up.
- If the code under test uses 'new' to instantiate the dependent behavior, use SwapNextInstance to replace the next 'new' with the faked object

Hope this clears things up.
Doron
Typemock Support
answered by doron (17.2k points)
0 votes
Thanks it does

Richard
answered by rfennell (6.8k points)
...