如何在android中对这行LayoutInflater.from()进行单元测试 [英] How to unit test this line of LayoutInflater.from() in android

查看:32
本文介绍了如何在android中对这行LayoutInflater.from()进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个简单的 RecycleView Adapter 并尝试测试该适配器的所有方法,但 onCreateViewHolder 对我来说很困难.

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);
}

我尝试使用 mockito 来构建 viewGroup 类的模拟,并在调用 getContext() 时返回 MockContext 的间谍,但这似乎是因为我返回 MockContext LayoutInflater.from() 返回空指针异常.

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.

这是我的测试

 @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);
}

提前致谢.

推荐答案

当我遇到同样的问题时,我遇到了这个问题.最后我自己解决了.

I came across this question when I was the same problem. I ended up solving it by myself.

假设你有一个简单的 onCreateViewHolder 像这样:

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)
    );
}

使用PowerMock 来模拟LayoutInflater 的静态实例.在下面的代码段中,我使用编号注释注释了您需要采取的所有步骤:

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);
    }

}

这篇关于如何在android中对这行LayoutInflater.from()进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆