Android Presenter, тестирующий IllegalStateException captor.capture(), не должен быть нулевым

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