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
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
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.