Hi Am building a simple RecycleView Adapter and am trying to test all the methods of the adapter but the onCreateViewHolder is been dificult for me.
@Override
public NewsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_news,parent,false);
return new NewsViewHolder(v);
}
I Try using mockito to build a mock of the viewGroup class and return a spy of the MockContext when getContext() is call but it seems to be that because am returning a MockContext LayoutInflater.from() return a null pointer exception.
This is my test
@Test
public void testOnCreateViewHolder() throws Exception {
ViewGroup vg = mock(ViewGroup.class);
MockContext mockContext = new MockContext();
MockContext spyContext = spy(mockContext);
when(vg.getContext()).thenReturn(spyContext);
NewsViewHolder vh = adapter.onCreateViewHolder(vg, 0);
Assert.assertNotNull("Response cant be null",vh);
}
Thanks in advance.
Use getLayoutInflater() to get the LayoutInflater instead of calling LayoutInflater. from(Context).
Stay organized with collections Save and categorize content based on your preferences. Instantiates a layout XML file into its corresponding View objects. It is never used directly.
The LayoutInflater class is used to instantiate the contents of layout XML files into their corresponding View objects. In other words, it takes an XML file as input and builds the View objects from it.
I came across this question when I was the same problem. I ended up solving it by myself.
Suppose that you have a simple onCreateViewHolder
like this:
@Override
public TeamsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new NewsViewHolder(LayoutInflater
.from(parent.getContext())
.inflate(R.layout.fragment_news_view_holder, parent, false)
);
}
Use PowerMock
to mock the static instance of LayoutInflater
. In the snippet below, I have annotated using numbered comments all the steps you need to take in order to make this work:
import android.test.mock.MockContext;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
// 1. signal JUnit to run this test PowerMockRunner
@RunWith(PowerMockRunner.class)
// 2. signal PowerMock to prepare the static instance of LayoutInflater for testing
@PrepareForTest({LayoutInflater.class})
public class NewsRecyclerViewAdapterTest {
// 3. LayoutInflater.from(context) returns an inflater,
// so we need to mock that one
@Mock
LayoutInflater mockInflater;
@Mock
View mockView;
@Mock
ViewGroup mockParent;
private int dummyTestId;
private MockContext mockContext;
private NewsRecyclerViewAdapter adapter;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
dummyTestId = 0x10000;
// 4. mock the static LayoutInflater in "LayoutInflater.from()"
// so that we can ask it to return a mockInflater that we moked above
mockStatic(LayoutInflater.class);
mockContext = new MockContext();
adapter = new NewsRecyclerViewAdapter(Arrays.asList(new NewsItem(), new NewsItem(), new NewsItem()));
}
@Test
public void onCreateViewHolderShouldReturnAValidViewHolder() throws Exception {
// 5. mock the context that comes from parent ViewGroup
when(mockParent.getContext()).thenReturn(mockContext);
// 6. mock the inflater that is returned by LayoutInflater.from()
when(LayoutInflater.from(mockContext)).thenReturn(mockInflater);
// 7. pass anyInt() as a resource id to care of R.layout.fragment_news_view_holder in onCreateViewHolder()
when(mockInflater.inflate(anyInt(), eq(mockParent), eq(false))).thenReturn(mockView);
// call onCreateViewHolder() to act
NewsViewHolder viewHolder = adapter.onCreateViewHolder(mockParent, dummyTestId);
// OKAY straightfoward right?
assertNotNull(viewHolder);
// this is not very important but I recommend it,
// it just returns the view sent to NewsViewHolder
// and verify it against the mockView that you inflated above
assertEquals(viewHolder.getItemView(), mockView);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With