R.Quintal
R.Quintal

Reputation: 53

How can I use mockito to Mock a class method that is inside another class

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:

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?

Upvotes: 0

Views: 6108

Answers (4)

Timothy Truckle
Timothy Truckle

Reputation: 15634

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.

Upvotes: 2

alayor
alayor

Reputation: 5045

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
    ...
  }
}

Upvotes: 1

Battle_Slug
Battle_Slug

Reputation: 2105

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.

Upvotes: 0

Plog
Plog

Reputation: 9612

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.

Upvotes: 0

Related Questions