Unit testing

4304
6
06-21-2010 10:08 AM
HaroldBostic
Occasional Contributor II
Hello,

This is a quick poll to see what the community is using to unit test their .NET extenstions?  In particular, what software do you use and what level of effort does it take to mock ArcObject objects for testing.

Thanks in advance
0 Kudos
6 Replies
RyanClark
New Contributor II
Along these same lines, is there anyone who can provide any resources for getting started unit testing specifically ArcMap add-ins in Visual Studio 2010?

Thanks,
Ryan
0 Kudos
AndrewMay
New Contributor
Hi
I've used a mixture of NUnit and Microsoft unit tests.  They both seemed to do the job so I wouldn't recommend one approach over the over.  I've looked around in the past to try and find details of how to mock Arcobjects but with very little success.  There's an interesting post here:

http://gis.stackexchange.com/questions/1393/how-to-unit-test-arcobjects-with-mocking

Basically ArcObjects is such a huge object model that your time is best spent improving the design of your system in order to reduce the amount of mocking you need to do - rather than putting all your efforts into the actual mocking.
0 Kudos
LukeBadgerow
New Contributor
I'm using a combination of NUnit and the standard Unit Testing framework provided by Visual Studio 2008. 

As for how much work it's making for me, it's hard to say.  I'm new to unit testing, and it feels like any time I make an arcobject call within a method that it's blowing up my test with the following error, so I'm starting to get a little worried that I'm going to have to refactor my entire code base so that I can pass every call to an arcobject as a parameter so that I can mock it for my tests.


Error 1 Test 'TestPostReconcile.ArcSDEUtilitiesTest.InitGeodataServerFromFileTest' failed: Test method TestPostReconcile.ArcSDEUtilitiesTest.InitGeodataServerFromFileTest threw exception:  System.Runtime.InteropServices.COMException: Retrieving the COM class factory for component with CLSID {A61F2A53-878A-4703-AB50-50FC0B8FEEEF} failed due to the following error: 80040111..
   at AutomatedReconcileCsharp.ArcSDEUtilities_Accessor.InitGeodataServerFromFile(String path)
   at TestPostReconcile.ArcSDEUtilitiesTest.InitGeodataServerFromFileTest() in C:\Documents and Settings\lbadgerow\My Documents\Visual Studio 2008\Projects\BatchReconcilePost\TestPostReconcile\ArcSDEUtilitiesTest.cs:line 81 C:\Documents and Settings\lbadgerow\My Documents\Visual Studio 2008\Projects\BatchReconcilePost\TestPostReconcile\ArcSDEUtilitiesTest.cs 81
0 Kudos
tugbakarakaş
New Contributor

Hi Luke,

Have you end up with any solution?

Could you suggest me any way to solve that problem?

ArcEmiEditorTest.DataConnectionTest.GetGDBConnection_ReturnTrue:

System.Runtime.InteropServices.COMException : Retrieving the COM class factory for component with CLSID {588E5A11-D09B-11D1-AA7C-00C04FA33A15} failed due to the following error: 80040154 Sınıf kaydedilmemiş (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).

0 Kudos
FridjofSchmidt
Occasional Contributor

Luke, Tugba,

You may get this kind of error if you don't bind to an ArcObjects license before running the test. You can do so in the Arrange section of your test or in a setup method that is run before all tests. For example, with NUnit, if you have all your tests in one assembly, it is sufficient to have one class with the SetUpFixture attribute and a one-line method to bind the license:

[SetUpFixture]
public class GetLicense
{
    [SetUp]
    public void TestSetUp()
    {
        RuntimeManager.BindLicense(ProductCode.Desktop, LicenseLevel.Standard)
    }
}

With regard to mocking, I prefer using NUnit with NSubstitute, and it works quite well. Luckily, in ArcObjects everything has an interface and can be mocked. Sometimes you need to mock several interfaces in one object, but NSubstitute lets you do this, or you can write your own interface and inherit as many of the ArcObjects interfaces as you need and then mock them with NSubstitute.

0 Kudos
JonMorris2
Occasional Contributor II

Yep, the Failed to create COM object error is always due to licensing. As Fridjof says, you need to activate your license before trying to create any Arcobjects.

You don't need to do this if you are using mocks though. I've been testing with Visual Studio 2010 unit tests and Moq - there is very little doc available on how to use Moq with ArcObjects, but it's quite easy to figure out with the quickstart guide. You just have to remember to add every cast, call, return value, etc. to your mock. Any time you need an actual object in your test code, just use mock.Object.

For example, here's a FeatureWorkspace that has an AliasName property and you can call the OpenFeatureClass method:

            // mock feature workspace object
            // has AliasName and can OpenFeatureClass
            var mockFeatureWorkspace = new Mock<IFeatureWorkspace>();
            var mockFC = new Mock<IFeatureClass>();
            mockFC.Setup(x => x.AliasName).Returns(featureClassName);
            mockFeatureWorkspace.Setup(x => x.OpenFeatureClass(It.IsAny<string>())).Returns(mockFC.Object);
            GeodatabaseManager.FeatureWorkspace = mockFeatureWorkspace.Object;

GeodatabaseManager and featureClassName are variables used in my test.

0 Kudos