1
@Component
Class A{
   public String method1(){
       ClassB bObject = new ClassB();
       bObject.makeHTTPCallAndConvertResponseToJSONString();
   }
}

Class ATest{
    @InjectMocks
    ClassA aObject;

    public String testMethod1(){
        // how to test aObject.method1();
        // I want to mock new bObject that is created
    }
}

Need to mock the bObject that is getting created. Want to know if this is possible. Looked through all the relative questions on the same topic but couldn't find any. Is this a limitation of Mockito?

Vineeth Chitteti
  • 1,454
  • 2
  • 14
  • 30
  • This looks like the same as https://stackoverflow.com/questions/5920153/test-class-with-a-new-call-in-it-with-mockito – Ankit Gupta Jan 24 '18 at 07:16
  • Thank you. I tried that. Tried setting A aObj = spy(new A()); as well as A aObj = new A(); A aObjRef = spy(A); But both of them were throwing errors. I'll paste the errors shortly. – Vineeth Chitteti Jan 24 '18 at 10:49
  • 1
    mockito only lets you mock things that you inject into the class under test. you can try powermock or jmockit to overcome this limitation, or refactor the class you're testing – Jacob Botuck Jan 24 '18 at 15:43
  • @JacobSTL: https://stackoverflow.com/questions/5920153/test-class-with-a-new-call-in-it-with-mockito I understand the limitation, but it is not officially documented anywhere. And a solution to the same problem was tried here. But it is not working for me. – Vineeth Chitteti Jan 25 '18 at 08:45
  • 1
    even if you got spy to work with out errors, the result would be that you could fake method1. Faking method 1 is not what you want. You are testing method1 and need it to be real. You just want the logic in method1 to interact with a mock ClassB which isn't possible if method1 creates the ClassB – Jacob Botuck Jan 25 '18 at 16:37
  • @JacobSTL Thanks. Finally realized it is untestable code.. – Vineeth Chitteti Jan 26 '18 at 08:56

3 Answers3

1

You cannot mock the objects which are local to a method. You can only mock class level object. Looking at the piece of code you have shared, I would suggest there is no need to unit test the method method1 (as it is simply invoking other method, there are no conditionals or loops involved here). It will be better to unit test "makeHTTPCallAndConvertResponseToJSONString" method of ClassB

codeLover
  • 2,571
  • 1
  • 11
  • 27
1

I don't think that you can mock an object that is created using 'new' keyword in the method you want to test. However you can create a public getter method for creating that object and then mock the new method.

Here's a generic code for your understanding -

//your method
public void someMethod() {
   ...
   Object object = new Object();
   ...
}

getting a new object from another public method.

//new implementation
public void someMethod() {
   ...
   Object object = getObject();
   ...
}

public Object getObject() {
   return new getObject();
}

now you can mock the getObject method and return your mocked object from this method.

Akash Chandwani
  • 550
  • 1
  • 9
  • 20
0

You need to convert the bObject to Class Level Object from Local Object.

Then you can Mock it like below:

@RunWith(MockitoJUnitRunner.class)
public class ATest {

  @Mock
  private ClassB  bObject;

  private ClassA aObject;

  @Before
  public void setUp() throws IOException {
      aObject = new ClassA(bObject);
  }

  @Test
  public String testMethod1(){
      String mockedJsonString = "{'sample':'string'}";
      when(bObject. makeHTTPCallAndConvertResponseToJSONString()).thenReturn(mockedJsonString);
      // Do whatever you want to test and verify
  }
}
Sahil Chhabra
  • 10,621
  • 4
  • 63
  • 62