Kotlin绑定可调用引用不一致

时间:2017-06-09 11:17:52

标签: reflection kotlin

今天我在Android应用程序中为我的Presenter创建单元测试,我发现与绑定的可调用引用有些不一致。它正在开发中还是语言错误?我在kotlin 1.1中发现that支持绑定的可调用引用。但是我的代码在kotlin 1.1.2-4中失败了。

在我的演示者类中,测试方法从数据库中读取数据,而dao.getAllItems()方法在视图列表中没有参数 - &gt; view.showData(List<Item>)

我正在使用Mockito,RxJava2和Room Persistance库。

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) }
                )
    }
}

我已为onGetItems()方法

创建了测试
@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)
    }
}

当我按上述设置时,测试通过没有问题。但是当我改变线路时 { data -> view.showData(data) }

{ view::showData }

然后我的测试失败说

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

是语言错误吗?因为易受攻击的代码可以很好地编译并运行,所以它只会导致根本不调用该方法,而不会出现任何错误。

为了澄清,用Java 8编写的相同代码工作正常,lambda参数正确传递给方法引用。正如您在Kotlin中看到的那样,绑定可调用引用在与不带参数的方法一起使用时工作正常,否则根本不会调用它们。

1 个答案:

答案 0 :(得分:3)

你应该改变

{ data -> view.showData(data) }

(view::showData)

正确传递方法引用。这样,使用(),您就可以将方法引用作为subscribe方法的参数传递。

使用{},定义一个新函数,其中lambda将赋予subscribe方法。

写下

{ view::showData }

相当于

{ it -> view::showData }

这是一个忽略其参数的函数,并返回方法引用view::showData