views:

260

answers:

3
+4  Q: 

unit test smell

I am trying to change my unit testing of ArcGIS, and start using mocks (I use rhino).
When I started to get into writing the tests, I noticed I have to start mocking a lot of objects, and stub a lot of methods for even a single test to pass.
For example - my controller first gets a RelationshipClass (so I need to stub the IWorkspace and the returned IRelationshipClass), then also gets an IFeature (A stub), and finally calls stubRelClass.GetRelatedObjects(stubFeature), to return an ISet of other IFeatures.

Is it normal to have to stub so many objects and methods just to make it pass? I also feel like I really need to step over the code (yeah - I know I should have written the tests first, I am still trying this one), in order to figure out what to stub out next, and what I should return.

I am also having problem with mocking com classes which implement more than one interface. In the production code I QI them between the interfaces. How can I create a mock that implements both interfaces at runtime?

+3  A: 

Depending on your injection chain, yes, sometimes you have to mock a lot of objects. If you're going multiple levels deep though, it may be indicative of a design fault - objects that are relying on data that is three layers down into your API may not be loosely coupled. You should be able to nip the chain in the bud by just returning a fake object of some kind at some point that has the necessary properties that the layer you're testing at needs.

You should also be able to do most of your mocking in a [SetUp] method and then have each test just change one or two things.

For mocking multiple interfaces, Rhino has the concept of a MultiMock. I believe the syntax you're after is:

var mock = 
    MockRepository.DynamicMultiMock<MyType>(
              typeof(Interface1), 
              typeof(Interface2), 
              ....);
womp
About introducing an object that cuts the deep levels - it will "save" me from mocking some more objects (since this one object will cover for them), but I'd still need to mock about the same amount of methods, right? Or am I getting this wrong?
Noam Gal
The point is not to "save you" from mocking more objects. The point is that the test is trying to tell you that there's a missing concept in there, that's why it's so complicated.
Steve Freeman
+2  A: 

To me it sounds like untestable code, which is a smell :-(

I would recommend reading http://misko.hevery.com/code-reviewers-guide/. The author is coach responsible for teaching google developers in the testing area. In the article he shows how you can write testable and untestable code.

Further recommended reading: Clean Code (Robert C. Martin) - main focus on how to write clean (which corresponds to testable) code. Working effectively with legacy code (Michael Feather) - shows ways to get untested and untestable code under control.

jens
and if you don't mind a brief commercial break... http://www.mockobjects.com/book
Steve Freeman
+3  A: 

It might be a sign of high coupling - which in turn implies a need to reduce dependencies (which will improve design and testability). As a rough guideline, an object should have around 4-6 collaborators max. Anything over that would set off my alarms.

http://stackoverflow.com/questions/59195/how-are-mocks-meant-to-be-used

Gishu