So let’s start at the beginning. And in the beginning you do this:
1 |
<span style="color: #000000;">RealLogger fake = Isolate.Fake.Instance<RealLogger>();</span> |
That’s it, you created a fake of the type RealLogger. On this fake you can set behavior and verify methods. In addition, this is an object which you can call methods on. It is similar to MockManager.MockObject<> API in reflective, or RecorderManager.CreateMockedObject<>() in Natural.
The Future
Now, if you supplement it with the following line:
1 |
<span style="color: #000000;">Isolate.Swap<RealLogger>().With(fake);</span> |
You swap the next instance of RealLogger that will be created with the fake. Which is similar to MockManager.Mock<>() in Reflective and a new statement inside the recording block in Natural Mocks.
You cannot use WhenCall or Verify on a real object – only on objects that went through the Instance method. So in the case of our future swapped object, the test will look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span style="color: #000000;">[TestMethod]</span> <span style="color: #000000;">[Isolated]</span> <span style="color: #000000;"><span class="kwrd">public</span> <span class="kwrd">void</span> FutureInstance_VerifyMethodWasCalledAndStubbed()</span> <span style="color: #000000;">{</span> <span style="color: #000000;"> RealLogger fake = Isolate.Fake.Instance<RealLogger>();</span> <span style="color: #000000;"> Isolate.Swap<RealLogger>().With(fake);</span> <span style="color: #000000;"> Isolate.WhenCalled(() => fake.Increment()).IgnoreCall();</span> <span style="color: #000000;"> RealLogger logger = <span class="kwrd">new</span> RealLogger();</span> <span style="color: #000000;"> logger.Increment();</span> <span style="color: #000000;"> Isolate.Verify.WasCalledWithAnyArguments(() => fake.Increment());</span> <span style="color: #000000;">}</span> |
And if you call this instead of the last line, you’ll receive an exception:
1 |
<span style="color: #000000;">Isolate.Verify.WasCalledWithAnyArguments(() => logger.Increment());</span> |
Note that the Swap statement can be anywhere after Instance, and doesn’t have to follow immediately. If you replace the Swap and WhenCalled lines in our small example, the result will be the same.
Creation
When calling Instance you can decide by the parameter you send it, what would be the default of the current or future instance behavior. The full signature looks like this:
1 |
<span style="color: #000000;">RealLogger fake = Isolate.Fake.Instance<RealLogger>(Members.CallOriginal);</span> |
Here are the options you have (which can be later overridden per method using WhenCalled):
- Members.MustSpecifyReturnValues:The default, which is equivalent to the overload with no parameters. All void methods are ignored. If you don’t use WhenCalled on methods that return values, and call them, you will get an exception.
- Members.CallOriginal: All methods are called by their original implementation.
- Members.ReturnNulls: All void methods are ignored. Any method that returns referencees will return null. Value type methods return zeros.
- Members.ReturnRecursiveFakes: All void methods are ignored. Any method that returns referencees will return fakes, on which any method that returns references will return fakes, on which…. you get the point.
Recursive Fakes
The final one is pretty powerful. If you have a hierarchy of objects, and you don’t want to write a set of WhenCalled for every item in the hierarchy (SharePoint anyone?), now you don’t have to. Just specify a recursive fake on your top object.
For example, below fake is recursively faked. We want a specific behavior on the return value of its GetSon() method, so we use WhenCalled. What you don’t see here is that all other methods (and their children and grandchildren) are also faked. We can write our test and concentrate on what we need, not everything else.
1 2 3 4 5 6 7 8 9 10 11 12 |
<span style="color: #000000;">[TestMethod]</span> <span style="color: #000000;">[Isolated]</span> <span style="color: #000000;"><span class="kwrd">public</span> <span class="kwrd">void</span> RecursiveStubsWithExpectationOnSecondLevel()</span> <span style="color: #000000;">{</span> <span style="color: #000000;"> RealLogger fake = Isolate.Fake.Instance<RealLogger>(Members.ReturnRecursiveFakes);</span> <span style="color: #000000;"> SonOfLogger son = fake.GetSon();</span> <span style="color: #000000;"> Isolate.WhenCalled(() => son.DoSomething(1)).WillReturn(13);</span> <span style="color: #000000;"> Assert.AreEqual(13, son.DoSomething(10));</span> <span style="color: #000000;"> Isolate.Verify.WasCalledWithAnyArguments(() => son.DoSomething(10));</span> <span style="color: #000000;">}</span> |