1

Consider a playfield, with various player types (let's say Hunters and Animals), all moving on the playfield (and doing some other things). E.g., in a unit test for the Hunter class, there can be such test cases, as a Hunter collides with an Animal and a Hunter collides with another Hunter. The latter could look something like this.

public class TestHunter {

    private Hunter hunter; // SUT

    @Mock // <-- should we?
    private Hunter hunter2;

    // initialization code, not important...

    @Test
    public void testCollideWithHunter() {
        hunter.collideWithHunter(hunter2);
        assert(/* something with hunter, not important */);
    }

}

Question: should, in this case hunter2 (which is not the target of the tests), be mocked or not?

My conclusion is, that in this case hunter2 is just another dependency (although, it happens to be of the same class as the System Under Test), so it should be mocked. I would therefore be interested especially in hearing counter-opinions, i.e. why hunter2 should not be mocked?

0
3

why hunter2 should not be mocked?

I would normally not mock another class, unless I had a pressing need to. If you don't mock the above, then your test is going to exercise your real class, and your real code, in the instance of this test.

That's normally a good thing, I would suggest.

Given the above, where would I use mocking ?

  1. if that class was sufficiently complex that it may cloud issues around the the test if/when it fails
  2. (more importantly) if I can't instantiate that dependent class in a suitable fashion for the test. e.g. does it represent a remote system (a database) or some such access ? Does it take a long time or a lot of dependencies in order to instantiate or run within the test ?

Briefly, I would opt for the real class wherever practical. Mock judiciously, when you have difficulty using the original class.

2

As often - it depends.

Mocking is not an end in itself, its goals are to make your automatic tests simpler, faster and it should help to test things in better isolation. If the creation of a second "Hunter" object is not significantly more complicated than the creation of a mock object (for example, if a "Hunter" object can be easily created with a few parameters in main memory, without the need to pull it from a database or other external resource), then using a mock can make things unnecessary complicated and it becomes pointless.

You should also consider how collideWithHunter is implemented internally. When it calls a bunch of other complex methods of the second Hunter object, for which you have already written individual unit tests, then mocking those methods out can make sense. In this situation, you may want only to validate the method collideWithHunter in isolation, and not those other methods. If, however, collideWithHunter is just using some getters and setters of the second object, using a mock won't help you to catch the root cause of any regressions quicker or more easily.

Note that all I wrote above is also true when you have two objects of different classes, this is in no way special to the situation where you have two objects of the same class.

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.