fridjof

Faking ArcObjects with Typemock Isolator?

Discussion created by fridjof on Nov 13, 2012
Latest reply on Nov 22, 2012 by fridjof
Hi all,

While diving into unit testing and isolation frameworks, I wanted to try Typemock Isolator to write unit tests for some legacy ArcObjects code. One of the main characteristics of good unit tests is that they test logical units in isolation, i.e., replacing dependencies with fakes. Typemock Isolator seems to have some advanced capabilities for this purpose.

In the production code, there are numerous occurrences of ArcObjects classes being instantiated, such as:
private void doSomething()
{
  ...
  IFields fields = new FieldsClass();
  this.doSomethingElse(fields);
  ...
}

What I basically want to do is to write tests in which I can test the logic of the production code units without accessing any real ArcObjects instances, and also without having to make any changes to the production code before writing tests.

However, there are several issues. First of all, even if I want to fake an ArcObjects class in Typemock Isolator, I need an ArcObjects license. If no license was initialized, the first line of the following method will fail with a COMException.
[Test]
public void SwapAllInstances_OfFieldsClass_SwapsFieldsClassCreatedWithNew()
{
    // Arrange
    FieldsClass fields = Isolate.Fake.Instance<FieldsClass>();
    Isolate.Swap.AllInstances<FieldsClass>().With(fields);

    // Act
    IFields newFields = new FieldsClass();

    // Assert
    Assert.That(newFields, Is.Not.InstanceOf<FieldsClass>());
}

This is actually against the idea of unit tests where I want to get rid of any external dependencies: If for some reason an ArcObjects license is not available in the test environment, the tests will fail - but only because the license could not be initialized. I repeat, for the purpose of the tests I'm not interested in any real ArcObjects instances, therefore a license shouldn't be required.

But second, even if I do initialize an ArcObjects license, in the above method the Assert will fail because the IFields variable newFields created with new is in fact an instance of ESRI.ArcGIS.Geodatabase.FieldsClass instead of the fake I expected from Isolator!

I'm currently trying to sort this out with Typemock's support, but I would also like to know from Esri if they have any guidelines for writing unit tests for ArcObjects code, and if (and how) it is possible to fake any ArcObjects instances created in the production code. Is there an isolation framework that can do this? Can it be done with Typemock Isolator but requires some steps that I missed?

Are there any ArcObjects developers out there who came across the same issue and found a solution?

Best regards,
Fridjof

Outcomes