1

I'm writing an integration test in Java using JUnit, Mockito, and ReflectionTestUtils. I have the following situation:

Source code that I want to test:

class AClassINeed extends SomeClass{


  public method_I_need_to_call(){

    //some code
    method_that_fails();
    // lots of other calls

  }

  private boolean method_that_fails(){
    // Instantiate a new local object of external dependency
    // Call a method from this new object ==> AKA FAILURE
  }
}

Inside my test method: I need to create a realObject here so that all the real code gets exercises. Except for the method that will fail. I'm currently trying like this:

AClassINeed realObject = new AClassINeed(Lots.class, Of.class, Parameters.class);
AClassINeed spyObject = Mockito.spy(realObject);
Method spyObjectPrivateMethod = spyObject.getClass().getDeclaredMethod("method_that_fails");
spyObjectPrivateMethod.setAccessible(true);
when(spyObjectPrivateMethod).thenReturn(true); // <== Syntax error "Cannot resolve method thenReturn(boolean)"

How can I achieve this? I cannot create a mock object of AClassINeed because I want execute all methods normally except the one that fails.

I also tried with ReflectionTestUtils like this:

Method failingMethod = realObject.getClass().getDeclaredMethod("method_that_fails", String.class, String.class);
failingMethod.setAccessible(true);
ReflectionTestUtils.setField(realObject, "method_that_fails", failingMethod); // <== Wrong! This cannot be done for methods

At this point, I'm stumped.

Is there a way for me to get that failing method to do nothing without mocking out the entire class?

Mugen
  • 1,417
  • 5
  • 22
  • 40
  • why would you want it to do nothing? I don't see the point of this, it's part of the unit you are testing – Stultuske Sep 17 '21 at 09:44
  • What's the reason the private method is failing? If it's because of business logic, then it's a legit failure. If it's because of an external dependency (for instance) then you'd need to mock that instead of the private method ... my point is: that private method is part of the object-under-test's own behavior and shouldn't be mocked. – lealceldeiro Sep 17 '21 at 09:46
  • @Stultuske Because that private method deals with a different architectural component that is outside the scope of integration test. – Mugen Sep 17 '21 at 09:46
  • 2
    then mock that "different architectural component" – Stultuske Sep 17 '21 at 09:47
  • is this method in you AClassINeed or in SomeClass that you extended you AClassINeed from? – Reza P. Sep 17 '21 at 09:48
  • @Stultuske I cannot mock it. The problem is that this private method in the very first line creates a new local object of the 3rd component. And in the second line it invokes a method from that local object. That's where it fails. I don't think there's any way for me to mock that local instance. :( – Mugen Sep 17 '21 at 09:50
  • @RezaP. It's in AClassINeed – Mugen Sep 17 '21 at 09:50
  • @lealceldeiro It's failing because of an external dependency. Please check my comments 2 steps above. It creates a local object of that external dependency. :( – Mugen Sep 17 '21 at 09:51
  • 2
    @Mugen you could create an "adapter" of the external dependency which does the actual instantiation. Then you can call the adapter in the private method to get the new instance of the external dependency when needed..... at test time, you can mock the adapter to return a stub instance of the external dependency, so your private method won't fail because of this. PS: please do not confuse this "adapter" term (careless) used here with the *Adapter* pattern – lealceldeiro Sep 17 '21 at 09:55
  • @lealceldeiro I cannot make out what you mean. But I will try to google every term you've mentioned until I can figure out and try what you mean. If it's possible for you to write a sample code as an answer that'd be really awesome. – Mugen Sep 17 '21 at 10:00
  • 2
    @Mugen then your problem is your design. create a factory that creates that local object, and mock the factory, or similar – Stultuske Sep 17 '21 at 10:15
  • will this match your question https://stackoverflow.com/questions/40742866/junit-skip-method-call-in-injectmock-method-in-a-test `jUnit skip Method-Call in injectmock-method in a test` – Srinath Ganesh Sep 17 '21 at 10:27
  • @SrinathGanesh Not really. Here we have a private method that we cannot mock so straightforwardly. Also, here the method is initializing a local object of a 3rd party dependency. – Mugen Sep 17 '21 at 11:32

0 Answers0