今天我在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中看到的那样,绑定可调用引用在与不带参数的方法一起使用时工作正常,否则根本不会调用它们。
答案 0 :(得分:3)
你应该改变
{ data -> view.showData(data) }
到
(view::showData)
正确传递方法引用。这样,使用()
,您就可以将方法引用作为subscribe
方法的参数传递。
使用{}
,定义一个新函数,其中lambda将赋予subscribe
方法。
写下
{ view::showData }
相当于
{ it -> view::showData }
这是一个忽略其参数的函数,并返回方法引用view::showData
。