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.
You can get the LinearLayoutManager from the RecyclerView by calling var layoutManager = (LinearLayoutManager)recyclerView.GetLayoutManager();
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:
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.
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 ).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With