views:

455

answers:

5

I am using dependency injection to supply mocks for code outside of my class under test. I find myself writing alot of the same code over and over as I need to mock out AuthProvider, ConfigurationManager, etc. which are used in the method I want to test. The method contains branches (if-then-else) and therefore I have multiple tests in place to test all execution paths of the method. I am instantiating each of the mocks several times (once in each test method) but am wondering if this is the wrong way around? Also I am putting up expectations for the mocks and preset responses which evidently are mostly copy-paste as such calls as to AuthProvider.Authenticate() are called in every method

In each method I setup a mock repository and at the end of each method I verify the mock repository. Should I prehaps have some sort of factory for creating these mocks along with setting their expectations and return values and if so how?

For implementation of mocks I am using RhinoMocks.

+5  A: 

"instantiating each of the mocks several times" is not a problem. Objects are free.

Just be sure you aren't defining the mock classes numerous times. Classes are expensive.

Also, you have a "setUp" method in a TestCase that allows you to create a fixture that is used by all tests. Yes, it's rebuilt for each test. No, that's not a problem unless it's painfully slow.

S.Lott
A: 

You might want to look at using the AAA style of test so that you have multiple tests with a common setup. Here's a decent example.

Garry Shutler
+1  A: 

Here is my take..

I would not use mock in the case... I would use a factory method to return a fake implementation of the class and use dependency injection to use this implementation instead.. this way you would avoid duplication and can reuse this implementation again n again... again this factory implementation need to be refactored properly i.e., no duplication..

Mocks, I guess should be used when you are testing some dynamic behavior.. something like.. did a method in sub-system was called when I perform some action on SUT.. and later on call verify() to verify this behavior... there is also a good article on Martin Folwer bliki Mock Aren't Stubs

StackUnderflow
A: 

Record and Replay frameworks like EasyMock fail if you dont set an expectation on a mock call. But frameworks like Mockito simply record all calls and let you verify only the ones that matter. So you dont have to set expectation on all methods in all tests.

And coming back to your Problem of instantiating Mocks in each test method, there's a better way than using setUp() method. Mockito provides a @Mock annotation. So you declare your variables(as fields) like: @Mock Repository repositoryMock

and just call initMocks() in setUp(). All mock objects declared are automatically available in your tests without explicitly creating Mocks.

Sathish
"Record and Replay frameworks like EasyMock fail if you dont set an expectation on a mock call." => This is incorrect. All mocking tools, EasyMock included, allow the developer to have "non-strict" expectations. In EasyMock, you do that by creating a "nice" mock with the "createNiceMock()" method.
Rogerio
+2  A: 

Assuming you're using NUnit, you can use instance variables for your Mocks and reset them in Setup/Teardown. If you see repeated patterns then do what you do with production code: refactor and extract helper methods that express what you're trying to achieve (if there's no commonality at all, then there's a problem with the design of the production code).

If there are significant divisions in setup, consider writing more than one test class for your production class.

Finally, think about whether your production class is just too busy and some of the behaviour ought to be extracted out to a helper object.

Listen to the Tests!

Steve Freeman
Thanks a lot for an insightful answer. I am wondering about how I would go about writing multiple test classes for the production class .. how would I name the multiple test classes?
Fadeproof
Name the test classes after what's significant about them -- just like all your other classes :)
Steve Freeman