Как сделать unit test (с помощью JUnit или mockito) кликов элементов recyclerview

В настоящее время я пытаюсь использовать unit test recyclerview addonitemclick listner с помощью junit или mockito. здесь мой код:

private void mypicadapter(TreeMap<Integer, List<Photos>> photosMap) {
    List<PhotoListItem> mItems = new ArrayList<>();

    for (Integer albumId : photosMap.keySet()) {
        ListHeader header = new ListHeader();
        header.setAlbumId(albumId);
        mItems.add(header);
        for (Photos photo : photosMap.get(albumId)) {
            mItems.add(photo);
        }


        pAdapter = new PhotoViewerListAdapter(MainActivity.this, mItems);
        mRecyclerView.setAdapter(pAdapter);
        //  set 5 photos per row if List item type --> header , else fill row with header.
        GridLayoutManager layoutManager = new GridLayoutManager(this, 5);
        layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                if (mRecyclerView.getAdapter().getItemViewType(position) == PhotoListItem.HEADER_TYPE)
                    // return the number of columns so the group header takes a whole row
                    return 5;
                // normal child item takes up 1 cell
                return 1;
            }
        });
        mRecyclerView.setLayoutManager(layoutManager);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.addOnItemTouchListener(new PhotoItemClickListener(MainActivity.this,
                new PhotoItemClickListener.OnItemClickListener() {
                    @Override
                    public void onItemClick(View view, int position) {
                        if (pAdapter.getItemViewType(position) == PhotoListItem.HEADER_TYPE) return;

                        Photos photo = pAdapter.getItem(position);
                        Intent intent = new Intent(MainActivity.this, DetailViewActivity.class);
                        intent.putExtra(PHOTO_DETAILS, photo);
                        ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
                                MainActivity.this,

                                new Pair<>(view.findViewById(R.id.photoItem),
                                        getString(R.string.transition_name_photo))
                        );
                        ActivityCompat.startActivity(MainActivity.this, intent, options.toBundle());
                    }
                }));
    }

Есть ли способ, которым я могу unit test: addOnItemTouchListener или OnItemClickListener/onitemclick, издеваться над функциональностью и т.д. Я новичок в модульном тестировании и смотрю онлайн в нескольких учебниках и довольно смущен. Любое пошаговое руководство по тестированию функций или любые предложения помогло бы. Кроме того, были бы полезны любые другие возможные тестируемые сценарии в этой функции. Спасибо!

Ответы

Ответ 1

В модульных тестах им не нужно иметь небольшие тестируемые фрагменты кода, я бы предпочел иметь 10 методов с единственной resposinbility, чем один метод для всех действий.

Все используемые входы должны поставляться как параметры для метода, чем вы тестируете, если на данном входе вы получите ожидаемый результат.

Не проверяйте, что вы не владеете. Тестирование View onClick() является частью задания AOSP. Вы можете проверить, как вы реагируете на onClickListener.

Пример:

Итак, если у вас есть метод вроде

goToDetailActivity(Photo photo){...}

добавьте onClickListener в свой RecyclerAdapter только для просмотра сообщений, которые на самом деле являются фотографиями, и вы можете проверить, например, если была вызвана goToDetailActivity (Фотофотография).

И при тестировании вы можете высмеивать теги, которые вам нужны (и не подлежат тестированию):

 RecyclerView recyclerView= Mockito.mock(RecyclerView.class);

 List<PhotoListItem> items = new ArrayList<>();
 Photo photo = Mockitio.mock(Photo.class);
 items.add(photo)); 

 PhotoViewerListAdapter adapter = Mockito.mock(PhotoViewerListAdapter);

 adapter.setData(items);
 recycleView.setAdapter(adapter);

 // simulate first item was clicked
 recyclerView.getChildAt(0).performClick();


 //Check if method was invoked with our object
 Mockito.verify(adapter).goToDetailActivity(photo);

Хорошая точка зрения учебник vogella mokcito.

Ответ 2

Я бы, вероятно, извлек анонимный внутренний класс, который вы создаете в addOnItemTouchListener, в отдельный класс.

Затем я бы написал соответствующие (единичные) тесты для метода onItemClick.

Это в значительной степени зависит от общего контекста вашего приложения и от того, что именно вы хотите проверить.

Обсуждение тестов модульных тестов и тестов интеграции довольно дорогое, и есть также некоторые путаницы и разные мнения вокруг того, что на самом деле является unit test.

Я бы посоветовал начать читать по теме из Мартина Фаулера превосходную серию статей - например, https://martinfowler.com/bliki/UnitTest.html Там также есть еще одна статья о двухлокальных тестах, которая должна помочь вам в отношении того, хотите ли вы использовать mocks или заглушки: https://martinfowler.com/articles/mocksArentStubs.html