0

I'm trying to use JUnit and Mockito to mock a end-to-end method (addSomething method). It's obvious that inside that method I use other methods. My doubts are:

  • To mock the end-to-end method I need to mock the other methods too, right?
  • How can I mock the methods that are inside the addSomething method?

A simple example for what I want is:

METHOD A

public int summing(int sum){
 int A = 5;
 int B = 23;

 sum = SumOfIntegers(A,B);
 return sum;
}

METHOD B

private int SumOfIntegers(int number1, int number2){

try{
    result = number1 + number2;
 }catch (Exception e) {
        e.printStackTrace();
 }
return result;
}

How do I mock the class's method A since it's calling a private method?

R.Quintal
  • 43
  • 1
  • 3
  • 13
  • 1
    @Michael thank you, aprecciate that. – R.Quintal Sep 06 '17 at 15:52
  • Can you tell us what exactly you are trying to do (using the posted code as support, i.e. don't say "the method", say "method XXX" instead). Thanks –  Sep 06 '17 at 15:52
  • @RC. I've edited the question but basically the main objective of my question is: it worth to mock the addSomething class? If yes, how can I do it? – R.Quintal Sep 06 '17 at 15:55
  • "To mock the end-to-end method I need to mock the other methods too, right?" Nope. If you mock `addSomething`, the implementation details of `addSomething` will not matter. You can have `addSomething` return a "fake" response (i.e. any appropriate String). – Michael Sep 06 '17 at 15:59
  • Possible duplicates: https://stackoverflow.com/questions/38181/when-should-i-mock, https://stackoverflow.com/questions/214092/what-is-a-mock-and-when-should-you-use-it –  Sep 06 '17 at 16:02
  • @Michael check the post now. I've updated a more clear example of what I want. – R.Quintal Sep 07 '17 at 11:22
  • Can you show the unit test code where you're trying to use this mock? – alayor Sep 07 '17 at 14:02
  • I cannot put here the code. But I can send to you a similar one. @alayor – R.Quintal Sep 07 '17 at 14:18

4 Answers4

2

Unittests verify the public observable behavior of a unit, which is the return values and the communication with its dependencies


The problem in your case is that there is a hidden dependency to ServerProxy. You should not instantiate it in that method, not in that class at all...

If you're following strictly the separation of concerns / single responsibility pattern the instantiation of dependencies is a responsibility of its own and should not be done by the object using the dependency.

In conclusion you should inject a ServerProxy object into your unit under test via dependency injection, preferably as a constructor parameter, most likely using a DI framework. In that case it is trivial to replace the ServerProxy with a mock which you can configure for your tests.

Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51
1

You would need to mock the class that addSomething() belongs to.

Suppose you have a class that uses that method.

public class ClassB {
  public String methodB(String jsonSomething) {
     ...
     String result = addSomething("{}");
    ...
  }  
}

public class ClassA {
  public String addSomething(String jsonSomething) {
     ...
  }  
}

In your test class for ClassB you would mock the classA object and you would specify behavior for addSomething method. You wouldn't need to specify any mocking behavior for what's inside addSomething.

@RunWith(MockitoJRunner.class)
public class ClassBTest {
  @Mock
  private ClassA classA;

  @Test
  testMethodB() {
    given(classA.addSomething(anyString())).willReturn("{}"); // Here you are specifying the mocked behavior for addSomething
    ...
  }
}
alayor
  • 4,537
  • 6
  • 27
  • 47
  • Hi @alayor. Thanks for your answer but I think you understand it bad. I don't have 2 classes like the code you provide here, I have one class with methods inside her. I'm trying to mock that class and test that method the only problem is that method has another methods inside and I just can't find a way to that. I'm new at unit tests and I'm going crazy about this. – R.Quintal Sep 07 '17 at 10:25
  • check the post now. I've updated a more clear example of what I want – R.Quintal Sep 07 '17 at 11:22
  • 1
    You should not mock the class you are testing. What you can do is put your private method in another class and then mock that class. – alayor Sep 07 '17 at 13:57
  • why shouldn't I mock the class I'm testing? – R.Quintal Sep 07 '17 at 14:06
0

If you are intending to mock methods of objects whose scope is local to the method under test then this is probably possible using something like PowerMock but really that is usually an indication that your code hasn't been written well to be easily tested.

I would reccomend refactoring your code to make sure that any objects with methods you want to mock should be included at class level using dependency injection. Mocking this with mockito is then very simple by marking these objects with @Mock annotation in your test and marking your class under test with @InjectMocks. This will then make sure a mock of the object is injected into the class under tests in your tests instead of a real instance of the object and you can then stub all the methods you like.

Plog
  • 9,164
  • 5
  • 41
  • 66
0

You don't mock methods, you mock whole classes and make them response the way you need if their methods are invoked. Then if you use method A inside a class, and this method A uses method B, you only mock method A. The code in the class is not exercised so you don't need to mock the whole chain. This is the point of mocking. Is that what you asking?

So you never mock methods you use in the Main method.

Battle_Slug
  • 2,055
  • 1
  • 34
  • 60
  • Thanks for your help. I've understood now what you've said, but I still can't make my unit test pass just by mocking method A I don't know why. – R.Quintal Sep 07 '17 at 10:28