使用Mockito单独测试Fragment类

ant*_*009 5 java android unit-testing mockito android-testing

添加@VisibleForTesting并保护.我的测试现在可以这个方法:

   @VisibleForTesting
    protected void setupDataBinding(List<Recipe> recipeList) {
        recipeAdapter = new RecipeAdapter(recipeList);
        RecyclerView.LayoutManager layoutManager
                = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
        rvRecipeList.setLayoutManager(layoutManager);
        rvRecipeList.setAdapter(recipeAdapter);
    }
Run Code Online (Sandbox Code Playgroud)

使用间谍对象更新了测试用例:但是,即使我创建了一个将被调用的间谍模拟,真正的setupDataBinding(配方)也会被调用.也许我做错了.

@Test
public void testShouldGetAllRecipes() {
    RecipeListView spy = Mockito.spy(fragment);
    doNothing().when(spy).setupDataBinding(recipe);

    fragment.displayRecipeData(recipe);

    verify(recipeItemClickListener, times(1)).onRecipeItemClick();
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试测试我Fragment班上的方法,如下所示.但是,我试图模拟方法来验证方法被调用正确的次数.但是,问题是我有一个private方法setupDataBinding(...)设置RecyclerView调用来自displayRecipeData(...).我想模仿这些调用,因为我不想调用真正的对象RecyclerView.我只想验证setupDataBinding(...)被调用.

我曾尝试使用间谍VisibleForTesting,但仍不确定如何做到这一点.

我试图孤立地测试片段.

public class RecipeListView
        extends MvpFragment<RecipeListViewContract, RecipeListPresenterImp>
        implements RecipeListViewContract {

    @VisibleForTesting
    private void setupDataBinding(List<Recipe> recipeList) {
        recipeAdapter = new RecipeAdapter(recipeList);
        RecyclerView.LayoutManager layoutManager
                = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
        rvRecipeList.setLayoutManager(layoutManager);
        rvRecipeList.setAdapter(recipeAdapter);
    }

    @Override
    public void displayRecipeData(List<Recipe> recipeList) {
        /* Verify this get called only once */
        setupDataBinding(recipeList);

        recipeItemListener.onRecipeItem();
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是我测试的方式.我已经添加了VisibleForTesting我可以帮助的想法.我试过使用间谍.

public class RecipeListViewTest {
    private RecipeListView fragment;
    @Mock RecipeListPresenterContract presenter;
    @Mock RecipeItemListener recipeItemListener;
    @Mock List<Recipe> recipe;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(RecipeListViewTest.this);
        fragment = RecipeListView.newInstance();
    }

    @Test
    public void testShouldGetAllRecipes() {
        fragment.displayRecipeData(recipe);
        RecipeListView spy = Mockito.spy(fragment);

        verify(recipeItemListener, times(1)).onRecipeItem();
    }
}
Run Code Online (Sandbox Code Playgroud)

孤立地测试上述内容的最佳方法是什么?

非常感谢任何建议.

Rad*_*ekJ 7

为防止调用真正的方法,请使用: Mockito.doNothing().when(spy).onRecipeItem();

在这里,您有最少的示例如何使用它:

public class ExampleUnitTest {
    @Test
    public void testSpyObject() throws Exception {
        SpyTestObject spyTestObject = new SpyTestObject();
        SpyTestObject spy = Mockito.spy(spyTestObject);

        Mockito.doNothing().when(spy).methodB();

        spy.methodA();
        Mockito.verify(spy).methodB();
    }

    public class SpyTestObject {

        public void methodA() {
            methodB();
        }
        public void methodB() {
            throw new RuntimeException();
        }
    }
Run Code Online (Sandbox Code Playgroud)

}