package nucleus.example.main; import android.app.Activity; import android.view.View; import android.widget.ArrayAdapter; import android.widget.CheckedTextView; import android.widget.ListView; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.concurrent.atomic.AtomicReference; import nucleus.example.R; import nucleus.example.base.ServerAPI; import nucleus.view.NucleusActivity; import static org.mockito.Matchers.any; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.powermock.api.support.membermodification.MemberMatcher.method; import static org.powermock.api.support.membermodification.MemberMatcher.methods; import static org.powermock.api.support.membermodification.MemberModifier.replace; import static org.powermock.api.support.membermodification.MemberModifier.stub; import static org.powermock.api.support.membermodification.MemberModifier.suppress; @RunWith(PowerMockRunner.class) @PrepareForTest({MainActivity.class, NucleusActivity.class}) public class MainActivityTest { public static final String TEXT = "test string"; private static final Class BASE_VIEW_CLASS = NucleusActivity.class; @Mock MainPresenter mainPresenter; @Mock ArrayAdapter arrayAdapter; @Mock CheckedTextView check1; @Mock CheckedTextView check2; @Mock ListView listView; MainActivity activity; @Before public void before() throws Exception { suppress(methods(BASE_VIEW_CLASS, "onCreate")); suppress(methods(BASE_VIEW_CLASS, "setContentView")); stub(method(BASE_VIEW_CLASS, "getPresenter")).toReturn(mainPresenter); replace(method(BASE_VIEW_CLASS, "findViewById")).with(new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { switch ((int)args[0]) { case R.id.listView: return listView; case R.id.check1: return check1; case R.id.check2: return check2; } return null; } }); activity = spy(MainActivity.class); PowerMockito.whenNew(ArrayAdapter.class).withArguments(activity, R.layout.item).thenReturn(arrayAdapter); } @Test public void testOnCreate() throws Exception { activity.onCreate(null); verify(check1).setText(MainPresenter.NAME_1); verify(check2).setText(MainPresenter.NAME_2); verify(mainPresenter).request(MainPresenter.NAME_1); } @Test public void testClicks() throws Exception { AtomicReference<View.OnClickListener> click1 = requireOnClick(activity, R.id.check1, check1); AtomicReference<View.OnClickListener> click2 = requireOnClick(activity, R.id.check2, check2); activity.onCreate(null); click1.get().onClick(check1); verify(mainPresenter, atLeastOnce()).request(MainPresenter.NAME_1); click2.get().onClick(check1); verify(mainPresenter, atLeastOnce()).request(MainPresenter.NAME_1); } @Test public void testOnItems() throws Exception { MainActivity activity = spy(MainActivity.class); PowerMockito.whenNew(ArrayAdapter.class).withArguments(activity, R.layout.item).thenReturn(arrayAdapter); activity.onCreate(null); ServerAPI.Item[] items = {new ServerAPI.Item(TEXT)}; activity.onItems(items, ""); InOrder inOrder = inOrder(arrayAdapter); inOrder.verify(arrayAdapter, times(1)).clear(); inOrder.verify(arrayAdapter, times(1)).addAll(items); } public AtomicReference<View.OnClickListener> requireOnClick(Activity activityMock, int viewId, View viewMock) { final AtomicReference<View.OnClickListener> listenerRef = new AtomicReference<>(); when(activityMock.findViewById(viewId)).thenReturn(viewMock); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { listenerRef.set((View.OnClickListener)invocation.getArguments()[0]); return null; } }).when(viewMock).setOnClickListener(any(View.OnClickListener.class)); return listenerRef; } }