如何进行unit testing(使用JUnit或mockito)recyclelerview项目点击

我目前正在尝试单独测试recyclerview addonitemclick listner,使用junit或mockito。 这是我的代码:

private void mypicadapter(TreeMap<Integer, List> photosMap) { List 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 testing:addOnItemTouchListener或OnItemClickListener / onitemclick,模拟function等。我对unit testing很新,并且在网上查看了几个教程并且非常困惑。 任何有关测试函数或任何建议的分步教程都会有所帮助。此外,此函数中任何其他可能的单元可测试方案都会有所帮助。 谢谢!

Related of "如何进行unit testing(使用JUnit或mockito)recyclelerview项目点击"

在unit testing中,拥有小的,可测试的代码块是很重要的,我宁愿使用单个可重用性的10个方法而不是所有操作的一个方法。

所有使用的输入都应作为parameter passing给方法,而不是测试在给定输入时是否会收到预期的输出。

不要测试你不拥有的东西 – 测试View的onClick()是AOSP工作的一部分。 您可以测试对onClickListener的反应。

你应该有一个处理逻辑的测试类。 在您的测试中,您实例化此类以测试它并模拟其他所有内容(通常很好的方法是通过构造函数传递依赖项)

例:

所以,如果你有像这样的方法

 goToDetailActivity(Photo photo){...} 

我将它包装在界面中,我们称之为View 。 在View您还要放置您的逻辑必须调用的所有其他方法,并且与视图组件,导航等交互视图相关。您应该拥有逻辑类,我们称之为Presenter

 public class Presenter { Presenter(View:view) { this.view = view; } public void onPhotoClicked(Photo:photo) { if (shouldDetailScreenBeOpened()) view.goToDetailActivity(Photo photo); else view.showError("error"); } private boolean shouldDetailScreenBeOpened() { // do caclualtions here ...} } 

我将我的适配器视为视图的一部分,因此它没有真正的逻辑。 因此,要将点击传递给Presenter您应该将它通过活动/片段( View实现)传递给Presenter (如果有人喜欢RxJava,可以使用RxBinding库)并调用它的onPhotoClicked(photo)方法。

在测试中,你必须模拟你需要的东西(而不是测试的主题):

  View view= Mockito.mock(View.class); Presenter tested = Presenter(view); Photo validPhoto = Mockitio.mock(Photo.class); Mockito.when(validPhoto.getUrl()).thanReturn("image.com") //call method which will be triggered on item click tested.onPhotoClicked(validPhoto) //Check if method was invoked with our object Mockito.verify(view).goToDetailActivity(validPhoto); //Check also not so happy path Photo invalidPhoto = Mockitio.mock(Photo.class); Mockito.when(invalidPhoto.getUrl()).thanReturn(null) //call method which will be triggered on item click tested.onPhotoClicked(invalidPhoto) Mockito.verify(view,never()).goToDetailActivity(invalidPhoto); Mockito.verify(view).showError("error") 

好的凝视点vogella mokcito教程 。

我可能会将你在addOnItemTouchListener创建的匿名内部类提取到一个单独的类中。

然后我会为onItemClick方法编写相关的(单元)测试。

这在很大程度上取决于您的应用程序的整体上下文以及您想要测试的具体内容。

关于unit testing与集成测试的讨论非常昂贵,并且对于真正的unit testing也存在一些混淆和不同意见。

我建议从Martin Fowler的优秀系列文章开始阅读更多关于这个主题的内容 – 例如https://martinfowler.com/bliki/UnitTest.html还有一篇关于测试双打的文章,一般来说,应该引导你关于是否你想使用模拟或存根: https : //martinfowler.com/articles/mocksArentStubs.html