1

I've class method like below which creates a local object and calls a method on that local object.

public class MyClass {
    public someReturn myMethod(){
        MyOtherClass otherClassObject = new MyOtherClass();
        boolean retBool = otherClassObject.otherClassMethod();
        if(retBool){
            // do something
        }
    }
}

public class MyClassTest {
    @Test
    public testMyMethod(){
        MyClass myClassObj = new MyClass();
        myClassObj.myMethod();
        // please get me here.. 
    }
}

When I'm testing myMethod, I want to mock otherClassObject.otherClassMethod to return something of my choice. otherClassMethod does some class to Message Queues and I don't want that in Unit test. So I want to return true when I do otherClassObj.otherClassMethod(). I know I must have used a factory for MyOtherClass instantiation in this case but it's legacy code and I don't want to change any code now. I see that Mockito doesn't provide this facility to mock MyOtherClass in this case but possible with PowerMockito. However, I could not find an example for above scenario but found only for static class. How should I mock local object inside a method of SUT ?

I also referred to some other OS questions like - Mocking methods of local scope objects with Mockito but they were not helpful.

A code example will be of great help.

Community
  • 1
  • 1
TechCrunch
  • 2,924
  • 5
  • 45
  • 79
  • You could use reflections to do that. – StackFlowed Apr 01 '15 at 18:39
  • Hold on; from your sample code your `otherClassObject`'s invocation is completely ignored. Is your sample code incomplete or couldn't you just mock the results of `myMethod`? – fge Apr 01 '15 at 18:39
  • @fge, I updated my code and question. – TechCrunch Apr 01 '15 at 18:48
  • And what do you want to test exactly from `myMethod()` here? I don't really see what you are after... – fge Apr 01 '15 at 18:56
  • @fge there is much code after retBool in myMethod. I did not place all that here. My question is - how to mock otherClassObject in this case. – TechCrunch Apr 01 '15 at 19:11

2 Answers2

4

If you are using PowerMockito you can use the whenNew method

It should look something like this:

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class)  //tells powerMock we will modify MyClass to intercept calls to new somewhere inside it
public class MyClassTest{

    @Test
    public void test(){
          MyOtherClass myMock = createMock(MyOtherClass.class);
          //this will intercept calls to "new MyOtherClass()" in MyClass
          whenNew( MyOtherClass.class).withNoArguments().thenReturn( myMock) );
          ... rest of test goes here

   }

Also this other SO post has example code too PowerMockito Mocking whenNew Not taking affect

Community
  • 1
  • 1
dkatzel
  • 31,188
  • 3
  • 63
  • 67
2

OK, this is not a real answer but with PowerMockito you can do this:

final MyOtherClass myOtherClass = mock(MyOtherClass.class);
// mock the results of myOtherClass.otherClassMethod();

PowerMockito.whenNew(MyOtherClass.class).withNoArguments()
    .thenReturn(myOtherClass);

// continue with your mock here

Now, not sure whether you actually need the result of this otherClassMethod here, but if you don't, I'd suggest you mock the results of myMethod() instead -- unless myMethod() is what you want to test because this other method has an influence on it, and yes, in this case a refactoring should be considered... And not delayed ad vitam aeternam...

fge
  • 119,121
  • 33
  • 254
  • 329