Controlling Collections and Indexers


Typemock Isolator can replace a collection in the code under test with user supplied collections.
This feature is useful when there's a need to return fake objects during iteration in our test code.

You can use this feature by calling Isolate.WhenCalled().WillReturnCollectionValuesOf() method.
When you call WillReturnCollectionValuesOf method the Isolator will replace implicitly the calls to GetEnumerator in the original collection with calls to
GetEnumerator of the test collection.

Example:
[TestMethod]
[Isolated]
public void SwapCollectionsExample()
{
    LogCollection source = Isolate.Fake.Instance<LogCollection>();
    RealLogger fakeLogger = Isolate.Fake.Instance<RealLogger>();

    // This is our test collection that will replace the real collection
    List<RealLogger> target = new List<RealLogger>();
    target.Add(fakeLogger);

    // GetEnumerator should be swapped
    Isolate.WhenCalled(() => source).WillReturnCollectionValuesOf(target);

    foreach (RealLogger logger in source)
    {
        logger.VoidCall();
    }

    Isolate.Verify.WasCalledWithAnyArguments(() => fakeLogger.VoidCall());


Notice the use of lambda expression in Isolate.WhenCalled(()=> source). You cannot use direct reference to the source collection. i.e. Isolate.WhenCalled(source)
 The Isolator can not replace collections that are defined in mscorlib.dll


Implicit Collection Creation


Creating fake collections just to access a specific index can be a tedious task. Isolator can create fake collection instead of the user.
By using Isolate.WhenCalled method on a collection with an integer indexer the user can use Isolator to implicitly create a fake collection.

Example:
[TestMethod]
[Isolated]
public void ImplictCollectionCreationExample()
{
1   LogCollection logCollection = new LogCollection();

2   RealLogger fakeLogger = Isolate.Fake.Instance<RealLogger>();
    Isolate.WhenCalled(()=> fakeLogger.ReturnFive()).WillReturn(100);
    // A fake collection at size of 3 is created
3    Isolate.WhenCalled(() => logCollection[2]).WillReturn(fakeLogger);

    Assert.IsNotNull(logCollection[0]);
    Assert.IsNotNull(logCollection[1]);
    Assert.AreSame(fakeLogger, logCollection[2]);
    Assert.AreEqual(100, logCollection[2].ReturnFive());
}

1 We create our test collection. The collection holds item of type RealLogger.

2 We create a fake logger and set expectation on the RealLogger.ReturnFive method.

3 Here the isolator creates implicitly LogCollection at size 3. When the code under test will access logCollection at index 2 our fakeLogger object will be returned.
Indexes 0 and 1 will return RealLogger objects with recursive fakes


This feature will work only on collections that are not defined at mscorlib.dll assembly.
This feature will work only work when using indexers with integer argument. The Isolator cannot assume the collection size if the indexer argument is
not a numeric type.
True Indexers
When faking indexers only specified index values will behave according to the specified behavior, other indice will behave according to the fake object default behavior.

Example:

public class ClaasWithIndexer
{
    public string this[int index]
    {
        get { return "Cat"; }
    }
}

[TestMethod]
public void TrueIndexersTest()
{
    var fake = Isolate.Fake.Instance<ClaasWithIndexer>(Members.CallOriginal);
    // We fake only the return value of index 2
    Isolate.WhenCalled(()=> fake[2]).WillReturn("Dog");

    // Here we call non fake indexer
    Assert.AreEqual("Cat", fake[0]);
    // Calling our fake indexer
    Assert.AreEqual("Dog", fake[2]);
}

In the example above we only fake the behavior index 2 of the indexer. All other indexes will result calling the original implementation.

See Also:

Copyright © Typemock Ltd. 2004-2010. All Rights Reserved.