vendredi 9 juin 2017

Kotlin bound callable references inconsistency

Today I was creating unit tests for my Presenter in Android app and I noticed some inconsistency with bound callable references. Is it under development or is it language bug? I found that in kotlin 1.1 bound callable references are supported. But my code fails with kotlin 1.1.2-4.

In my presenter class, tested method reads data from database and dao.getAllItems() method have no parameters while view takes list --> view.showData(List<Item>).

I'm using Mockito, RxJava2 and Room Persistance library.

class ItemsPresenter @Inject constructor(private val itemDao: ItemDao) : Presenter<ItemsView>
{
    val TAG = this.javaClass.name!!
    private val disposables: CompositeDisposable = CompositeDisposable()
    private lateinit var view: ItemsView

    override fun onCreate(view: ItemsView)
    {
        this.view = view
    }

    override fun onDestroy()
    {
        disposables.clear()
    }

    fun onGetItems()
    {
        Observable.fromCallable(itemDao::getAllItems)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        { data -> view.showData(data) },
                        { throwable -> view.showLoadingDataError(throwable.localizedMessage) }
                )
    }
}

I have created test for onGetItems() method

@RunWith(KotlinTestRunner::class)
class ItemsPresenterTest
{
    private lateinit var view: ItemsView
    private lateinit var dao: ItemDao
    private lateinit var presenter: ItemsPresenter

    @Before
    fun setup()
    {
        RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.io() }
        dao = mock(ItemDao::class.java)
        view = mock(ItemsView::class.java)
        presenter = ItemsPresenter(dao)
    }

    @Test
    fun onGetItemsTest()
    {
        val list = ArrayList<Item>()
        When(dao.getAllItems()).thenReturn(list)
        presenter.onCreate(view)
        presenter.onGetItems()

        verify(dao).getAllItems()
        verify(view).showData(list)
    }
}

When I have setup as above, the test passes without problems. But when I change line
{ data -> view.showData(data) }

to

{ view::showData }

Then my test fails saying

Wanted but not invoked:
itemsView.showData([]);

Is it language bug? Because vulnerable code compiles fine and runs, it just causes the method to not be invoked at all, without any errors.

To clarify, the same code written in Java 8 works fine, lambda argument is correctly passed into method reference. As you can see in Kotlin bound callable references work fine when used with methods that takes no parameters, otherwise they are not called at all.





Aucun commentaire:

Enregistrer un commentaire