Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I unit test RecyclerView , LinearLayoutManager in Robolectric?

How do I unit test RecyclerView, ScrollListener , LinearLayoutManager in Robolectric?

Im fairly new to this kind of testing but I really wanted to imitate gestures, especially scrolling.

like image 702
david Avatar asked Mar 16 '16 15:03

david


People also ask

How to get the linearlayoutmanager from the recyclerview?

You can get the LinearLayoutManager from the RecyclerView by calling var layoutManager = (LinearLayoutManager)recyclerView.GetLayoutManager();

Why should I use robolectric for unit testing?

If yes then, you must try Robolectric, it is a unit testing framework that allows Android applications to be tested on the JVM without an emulator or device. These are the main features of it:

What is the recyclerviewmatcher and how do I use it?

Using the RecyclerViewMatcher, you can not only perform actions on an item at a specific position in a RecyclerView, but also check that some content is contained within a descendant of a specific item. The RecyclerViewMatcher matcher worked great until we tried testing items that were somewhere off-screen.

How can I test a recyclerview?

In this post, I’ll show you an Espresso matcher that can be used to aid in testing RecyclerViews. The espresso-contrib library provides a RecyclerViewActions class that offers a way to click on a specific position in a RecyclerView (see instructions on configuring espress-contrib ).


Video Answer


1 Answers

I guess what you really wan't to test is your code and if it behaves as desired using these components.

Since the scope of your question is pretty wide, let me give it a use-case.:

Let's assume you have a fragment with a RecyclerView, which has a LinearLayoutManager. You want to test if a click on one of the items triggers the right method call on another layer. (Let's say you use MVP and that is the presenter)

A possible test could look like this.:

@RunWith(RobolectricGradleTestRunner::class)
@Config(constants = BuildConfig::class, sdk = intArrayOf(21))
class MyFragmentTest {

lateinit var fragment: MyFragment
lateinit var activityController: ActivityController<FragmentActivity>

@Before
@Throws(Exception::class)
fun setUp() {
    fragment = MyFragment()

    activityController = Robolectric.buildActivity(FragmentActivity::class.java)

    activityController.create().start().resume()

    activityController.get()
            .supportFragmentManager
            .beginTransaction()
            .add(fragment, null)
            .commit()
}

@Test
@Throws(Exception::class)
fun testClickEntry() {
    val recycler = fragment.view!!.findViewById(R.id.sideNavigationRecycler) as RecyclerView
    // workaround robolectric recyclerView issue
    recycler.measure(0,0)
    recycler.layout(0,0,100,1000)

    // lets just imply a certain item at position 0 for simplicity
    recycler.findViewHolderForAdapterPosition(0).itemView.performClick()

    // presenter is injected in my case, how this verification happens depends on how you manage your dependencies. 
    verify(fragment.presenter).onEntryClicked(MyNavigationEntry.XYZ)
}
}

Sorry for the syntax first of all, I use Kotlin in my tests.

I have to say though I'm not 100% happy with this by myself but i think its reasonable if you wan't to test the correct communication of your layers.

like image 200
Ostkontentitan Avatar answered Sep 18 '22 11:09

Ostkontentitan