I am trying to stub an IFeature with RhinoMocks, but I am having so much trouble doing it. Does anyone have experience with it?


Mocking a single interface is easy, but it will not help you very much in ArcObjects development. You are in a COM world, which is heavily interface-based, not to mention ESRI has chosen to take this orientation to an even higher level - e.g. the Feature coclass implements like 20 interfaces or so.

You can also simply implement the interface(s) in your own class, avoiding the RhinoMocks proxy indirection, but it does not give you a great advantage either.

Imagine you stub out the IFeature, IRow and IObject interfaces, which are commonly used together (in many cases interchangeably). Now, it's for example quite common to access the workspace properties from a feature, meaning you need to mock IFeature.Class property so that it returns an a mock object implementing at least IObjectClass and IDataset, from which you get a reference to the IDataset.Workspace, then mock the workspace object as well. This very quickly becomes a nightmare. For mocking out things like IFeature.OID, you can do that, but for any real-world scenarios it's next to unusable. You'd be basically implementing the esriGeodatabase library with mocks.

There are alternatives, though. For simpler testing scenarios, it is often easier to setup a file geodatabase, initialize the workspace in your unit test class setup, and disconnect upon its teardown. One downside is that you cannot use database-specific behavior (for example you cannot mimic the usage of Oracle SQL syntax as you are in a different workspace type). Other disadvantage is that you need to checkout/checkin the licence properly as well, which may limit running the unit tests in a dedicated build server.

Probably the best thing is to change your design - introduce a level of abstraction in your application for geodatabase access, which you can test against and provide mocks for, without having to deal with ArcObjects intricacies. Similar issue arises in many scenarios involving database access - but the data access layer is very rarely tested in such level of detail. The Repository design pattern (as well as other patterns in the same family) is most commonly used to overcome these issues. Depending on your current design and the extensiveness of your application, it might or might not be of much help, but it is very likely it could increase both code maintainablity and testability.

  • Thanks for the feedback. I have introduced a level of abstraction. I have wrapped the feature, and this wrapper is what I wanted to unittesst. I have tried the scenario with test data in a geodatabase, but it is very timeconsuming, and I am in a CI environment. – Morten Mar 10 '11 at 11:23
  • 1
    I don't have much experience with mocking, but I did created a project trying to wrap an IObject and simplifying geodatabase access. It still a young project, but I would like feedback on it. sourceforge.net/projects/gisactiverecord the svn is open to checkouts and for reading the code. let me know if it's useful or if anyone wants to help. – George Silva Mar 10 '11 at 12:07
  • 1
    @George: Took a brief look around the code and looks good. This kind of DAL makes unit testing way easier. I implemented something very similar (unfortunately cannot make the code public), but used Castle DynamicProxy for the individual entities. – Petr Krebs Mar 10 '11 at 13:15
  • @petr k. thanks! It's working properly, but there is still a long way here. I want code generation and would like to inject the code into properties, without needing to write them all over. There is significant ammount of code I need to standardize (exceptions, messages, etc). If you have any suggestions or wishes to contribute (anyone actually) just drop me a line. – George Silva Mar 10 '11 at 15:09
  • 1
    @George: The code injection part was exactly what I used DynamicProxy for. Code generation is a good idea, could perhaps be done either directly from an ArcCatalog addin or by processing an exported XML Geodatabase Schema document. – Petr Krebs Mar 10 '11 at 15:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.