Ankit
Ankit

Reputation: 135

How to unit test logic in an inner class using Mockito / Powermockito

I have the following class to test.

public class ClassToTest {

    private View view;

    public ClassToTest(View view) {
        this.view = view;
    }

    public void init() {
        view.add(new ParamClass.OnSomething() {
            @Override
            public void onSomethingElse() {
                view.doSomeWork();
            }
        });
    }
}

Where view is

public class View {
    public void add(OnSomething onSomething) {
    }

    public void doSomeWork() {
    }
}

I have mocked view object, but no clue how to test the logic marked "Some logic here to test"

ParamClass is final.

public final class ParamClass {

  public interface onSomething {
    public void onSomethingElse();
  }
}

Without making change to source, is there a way to unit test this using Mockito / Powermockito?

I'm trying to verify the invocation of doSomeWork()

@RunWith(PowerMockRunner.class)
@PrepareForTest({ ClassToTest.class })
public class TestClass {

    @Mock View view;

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void test() throws Exception {
        ClassToTest classToTest = new ClassToTest(view);
        PowerMockito.doCallRealMethod().when(view).add(Mockito.any(ParamClass.OnSomething.class));
        PowerMockito.whenNew(ParamClass.OnSomething.class)
                .withAnyArguments()
                .thenReturn(new ParamClass.OnSomething() {
                    @Override
                    public void onSomethingElse() {
                        view.doSomeWork();
                    }
                });
        classToTest.init();
        Mockito.verify(view, Mockito.times(1)).doSomeWork();
    }
}

Its throwing exception

java.lang.ArrayIndexOutOfBoundsException: 0

at org.powermock.api.mockito.internal.expectation.DefaultConstructorExpectationSetup.withAnyArguments(DefaultConstructorExpectationSetup.java:66)
at com.linkedin.android.lite.animations.TestClass.test(TestClass.java:29)

Upvotes: 1

Views: 4495

Answers (2)

Ankit
Ankit

Reputation: 135

I figured out how to do it. Updating the answer.

public class TestClass {

    @Mock View view;

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void test() throws Exception {
        ClassToTest classToTest = new ClassToTest(view);
        classToTest.init();
        ArgumentCaptor<ParamClass.OnSomething> captor =
        ArgumentCaptor.forClass(ParamClass.OnSomething.class);
        verify(view).add(captor.capture());
        ParamClass.OnSomething onSomething = captor.getValue();
        onSomething.onSomethingElse();
        Mockito.verify(view, Mockito.times(1)).doSomeWork();
    }
}

Upvotes: 1

Toofy
Toofy

Reputation: 861

Well what are you exactly trying to test? If there is code inside onSomethingElse that calls other objects/methods then you can simply mock all those other calls and then use Mockito.verify(mockObjectHere).methodCalled() on those methods that were called, if you just want to implement testing for behaviour.

Upvotes: 0

Related Questions