4

Let's say I have class MyClass with methods x(), y() and z(). Let's say x() calls y(), and y() calls z().

So everytime I test x() both y() and z() are called. In case of mocking the dependencies of MyClass I will have to mock the dependencies behavior inside x(), y() and z().

So if my tests for method x() are testXWhen1(), testXWhen2() and testXWhen3() I will have to repeat the expectations for my dependencies in each of the test methods. In the end, I have some code with the expectations for what happens inside y() and z() repeated for my three test methods. Any solution to avoid this?

One of my ideas was to try to test the actual x() method, but mocking y() and z(). In that case my instance of MyClass should be partly a mock and partly the real MyClass. Is it possible?

Another solution was to be strict about expectations in x(), but not about what happens in y() and z()... I think I can do that with @NonStrict instead of @Mocked, but it's not my favorite solution.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
antonio.fornie
  • 1,740
  • 2
  • 13
  • 23

3 Answers3

2

If you want to test method x() then you should mock method y().In That case there's no need to mock z() too 'cause you'll never reach call of z() inside the y() (y is mocked).Test your x, y and z methods in different tests.Use PowerMock.It has createPartialMock method.

shift66
  • 11,760
  • 13
  • 50
  • 83
  • 1
    I don't think it's useful to think in terms of testing 'methods' - it is the behaviour of the SUT you want to test, not a particular implementation. – blank Dec 13 '11 at 12:26
0

In the end, I have some code with the expectations for what happens inside y() and z() repeated for my three test methods. Any solution to avoid this?

Have you tried the 'Extract Method' refactoring?

Another solution was to be strict about expectations in x(), but not about what happens in y() and z()...

This is exactly what I do when testing a particular bit of functionality (albeit using JMock) - if the behaviour I'm testing is not dependent on the outcome of calls to dependancies I will explicitly use the JMock ignoring/allowing expectations. It makes the intent of the test much clearer and focused on what exactly is being tested.

blank
  • 17,852
  • 20
  • 105
  • 159
0

You can use JMockit's dynamic partial mocking feature, by passing the class or object to be partially mocked in the Expectations/NonStrictExpectations constructor.

In general, though, it's best to avoid the use of partial mocking, as it often indicates a lack of cohesion in the code under test, and leads to tests that are harder to understand.

For cases where you have a bunch of the same expectations being needed in several tests, there's always the option of creating reusable expectation blocks. You can encapsulate a number of expectations in a named "XyzExpectations" subclass, optionally with parameterized constructors, and instantiate it in any number of tests (the "expectations" subclass actually instantiated must be final). The same can be done with verification blocks.

Rogério
  • 16,171
  • 2
  • 50
  • 63