#android #unit-testing #mockito #android-mvp
#Android #модульное тестирование #mockito #android-mvp
Вопрос:
У меня простое приложение, основанное на mvp. Напишите тест для presenter. Используется Mockito для макетных данных. Я перехватываю данные обратного вызова (ArrayList) с помощью ArgumentCaptor. Мой тестовый класс
@RunWith(MockitoJUnitRunner::class)
class MainPresenterTest{
@Mock
lateinit var view:MainView
@Mock
lateinit var context:Context
@InjectMocks
lateinit var presenter: MainPresenter
@Captor
lateinit var captor: ArgumentCaptor<ArrayList<News>>
@Before
fun init(){
MockitoAnnotations.initMocks(this)
}
@Test
fun success(){
presenter.loadNews()
Mockito.verify<MainView>(view).onSuccess(captor.capture())
var data = captor.value
Mockito.verify(view).onSuccess(data)
Mockito.verify(view,never()).onError("")
}
}
Основной вид
interface MainView{
fun onSuccess(n:ArrayList<News>)
fun onError(e:String)
}
Но выбросить
java.lang.IllegalStateException: captor.capture() must not be null
Example of correct verification:
verify(mock).doSomething()
Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
Ответ №1:
На самом деле вам не нужно определять его как переменную класса lateinit . В вашем методе тестирования определите переменную метода следующим образом
@Test
fun success(){
presenter.loadNews()
val captor: ArgumentCaptor<ArrayList<*>> = ArgumentCaptor.forClass(ArrayList::class.java)
Mockito.verify<MainView>(view).onSuccess(captor.capture())
var data = captor.value
Mockito.verify(view).onSuccess(data)
Mockito.verify(view,never()).onError("")
}
}
Кроме того, вы должны подтвердить данные от captor. Вместо этого
Mockito.verify(view).onSuccess(data)
сделайте что-то вроде этого
assertEquals("x", data.size())
Комментарии:
1. ArgumentCaptor<ArrayList<*>> = ArgumentCaptor.forClass(ArrayList::class.java ) неверный аргумент. требуется ArrayList<Новости> найден ArrayList<*>
2. Затем попробуйте не указывать тип, подобный этому val captor = ArgumentCaptor.forClass(ArrayList::class.java )