views:

289

answers:

4

In .net, unlike in Java, methods are not virtual by default. In order to use most mock object frameworks, you either have to mark the methods that you want to use on your mock as virtual on the `real' object, or you have to have an interface that you can mock that the class under test will accept in lieu of the implementation.

It seems like bad form to go and mark every method as virtual, but it also seems like bad form to define an interface for every single class.

What is the best thing to do?

A: 

Who says that you mock object has to derive from the same class hierarchy?

It's much easier to create a simple standalone class that has the needed interface and create instances of that object.

You can even create a hierarchy of mock classes and use that for purpose of unit-testing.

Milan Babuškov
Thanks for the response. I see what you are getting at, but in order for the class-under-test to work with the mock, it does have to be derived from either the same interface that the real object implements or directly from the real class. I think the mock must satisfy the `Is A' relationship.
dnewcome
@dnewcome: Looks like you're right. What I wrote would be much better for languages that use duck-typing.
Milan Babuškov
+1  A: 

If I have to choose between the two, I'd go with the interface thing. An interface is meant to define a contract, which is basically what a mock object is going to adhere to. Marking a method as virtual might have unanticipated side effects. It affects the design of the actual class being mocked. An interface merely defines method names and will have no effect on the real class.

Mehrdad Afshari
This makes sense to me from a correctness standpoint. In .net, to me defining a virtual method indicates that the class designer intends this to be overridden somewhere. It also can't be inlined, etc, as far as side effects. You are right on about the mock adhering to the contract I think.
dnewcome
A: 

The best thing is to use your head. Think about your scenario, if it makes more sense to use virtual then do that. If however an interface is better suited for your task then do that.

So really I see it as this in adding new functionality

  • Inheritence: Use virtual methods.
  • Composition: Use interfaces.

I'm sure there are a bunch of caveats to this. So just use your head and do what is easiest in your scenario.

Aaron Weiker
What you said is definitely best practice for designing classes. The problem I have is that I don't really have the call for either. The classes that I'm mocking are generally standalone in behavior, and I don't need virtual methods other than to enable mocks.
dnewcome
If you are just trying to mock something that can't be mocked there are a few options. First see if TypeMock can help you out. If not, then I would put a Facade around it and have that implement an interface. From there you can just simply mock to the interface and get on with life. Keep is simple!!
Aaron Weiker
+3  A: 

My rule of thumb is to define the interface if I expect to have multiple implementations, either actual concrete application classes or a single application implementation and a fake implementation for unit testing. If I only expect a single implementation and the class doesn't need faking (most don't), then I'll go the virtual method route and refactor to an interface as needed.

tvanfosson
I like the idea of treating test doubles as planned implementations of the interface. I'm not sure if I like making the others virtual unless it's part of the class design, but then again, if it turns out you need to mock something later, changing code just for that stinks.
dnewcome