0

I am trying to understand how to use mocking with Mockito, but I don't know how to handle the following situation:

  1. Where the method in the class which you are trying to mock is private.
  2. Where the method should remain in the class.
  3. Where making the method public could result in future programmers making the code behavior unexpectedly, thus should remain private.
public class Foo {

  private final int secret;

  public Foo(int s) {
    secret = s;
  }

  public void bar() {
    int sum = sum(0);
  }

  private int sum(int i) {
    if (i == 1) {
      return i * secret;
    }
    secret -= i;
    return i;
  }
}

I am trying to mock Foo and test that sum is behaving correctly, but I'm struggling to decide how best to do so with minimal impact. Should I change the sum method to public? How do you go about testing this behavior?

alwaysboots
  • 141
  • 1
  • 2
  • 12

3 Answers3

0

Your example is very cryptic, and it is difficult to understand the purpose of the method.

You say you are trying to test sum is behaving correctly. To do this you should probably not be mocking Foo. Either:

  • Test the functionality of sum through the pubic methods of class or,
  • Move the method and state of secret field to another class which can expose sum as a public method.

Making a method public for the purpose of testing is not advisable, it usually means you don't have the right design and restructuring the code would be more beneficial.

Anuj Shah
  • 71
  • 4
  • Thank you for your response. Indeed, the method is difficult to understand, but I simply wanted to use a method that uses and modifies a field within the class. How would you test sum through the public methods i.e. through `bar`? – alwaysboots Mar 08 '15 at 11:44
  • The sum method seems to have two purposes. One is to return a number, the other to change the state of the secret field. Both the return value and the field must have some purpose for the class and the bar method and must alter the behaviour of these in some way. If it doesn't have a purpose then you should refactor. – Anuj Shah Mar 08 '15 at 21:17
0

You can't mock private methods using mockito. Try powermock

See what the mockito page says about mocking private methods. https://code.google.com/p/mockito/wiki/MockitoAndPrivateMethods

CKuharski
  • 314
  • 3
  • 14
0

you have more less 4 ways to do it:

  1. do not test it - test visible methods that use the private method
  2. increase the visibility of the method and document it as @VisibleForTesting
  3. use specialized tools like powermock or reflection to fire the method
  4. refactor your code and move private method to package private class

hard to tell which one is best for you, it depends on specific case

piotrek
  • 13,982
  • 13
  • 79
  • 165