lundi 13 mars 2017

Android. Mockito uses real objects instead of mock

So, I've just writing simple test. The problem is that test runner runs real 'Repository' class code instead of mock code... Do you have any idea why could I get an exception on this?

Test class

class SingInFacebookPresenterTest {

    @Mock
    private lateinit var view: SignInFacebookContract.View

    @Mock
    private lateinit var repository: Repository

    @Captor
    private lateinit var callback: ArgumentCaptor<RepositoryCallback.FacebookLoginImp>

    private lateinit var presenter: SingInFacebookPresenter

    private val serverToken = "token"

    @Before
    fun init() {

        MockitoAnnotations.initMocks(this)

        presenter = SingInFacebookPresenter(MockContext(), repository, view)
    }

    @Test
    fun facebook_login_success() {

        //Given
        val token = "token"
        val serverToken = "server token"

        presenter.loginViaFacebook(token)

        //When
        verify(repository).loginViaFacebook(token, callback.capture())


        callback.value.onSuccess(serverToken)

        //Then
        verify(view).success(serverToken)
    }

Presenter

class SingInFacebookPresenter(var context: Context, var repository: Repository, var view: SignInFacebookContract.View): SignInFacebookContract.Presenter {

    public override fun loginViaFacebook(token: String) {
        repository.loginViaFacebook(token, object : RepositoryCallback.FacebookLoginImp {
            override fun onSuccess(token: String) {
                view.success(token)
            }

            override fun onFailure() {
                view.onFailure()
            }

        })
    }

Repository

open class Repository(context: Context) {

    init {
        ApiHelper(context)
    }

    private var facebookLoginPresenterCallback: RepositoryCallback.FacebookLoginImp? = null

    fun loginViaFacebook(token: String, facebookLoginPresenterCallback: RepositoryCallback.FacebookLoginImp?) {
//        this.facebookLoginPresenterCallback = facebookLoginPresenterCallback
        val signInResponse = ApiHelper.signInViaFacebook(token)
//        signInResponse.enqueue(signInFacebookCallback)
        signInResponse.enqueue(object : Callback<SignInResponse> {
            override fun onResponse(call: Call<SignInResponse>?, response: Response<SignInResponse>?) {
                if (response!!.isSuccessful) {
                    val token = response.body()?.token ?: return
                    facebookLoginPresenterCallback?.onSuccess(token)
                    return
                }
                facebookLoginPresenterCallback?.onFailure()
            }

            override fun onFailure(call: Call<SignInResponse>?, t: Throwable?) {
                facebookLoginPresenterCallback?.onFailure()
            }
        })
    }

    private val signInFacebookCallback = object : Callback<SignInResponse> {
        override fun onResponse(call: Call<SignInResponse>?, response: Response<SignInResponse>?) {
            if (response!!.isSuccessful) {
                val token = response.body()?.token ?: return
                facebookLoginPresenterCallback?.onSuccess(token)
                return
            }
            facebookLoginPresenterCallback?.onFailure()
        }

        override fun onFailure(call: Call<SignInResponse>?, t: Throwable?) {
            facebookLoginPresenterCallback?.onFailure()
        }
    }
}

Exception:

Exception in thread "OkHttp Dispatcher" java.lang.NoSuchMethodError: okhttp3.internal.Platform.log(Ljava/lang/String;)V
    at okhttp3.logging.HttpLoggingInterceptor$Logger$1.log(HttpLoggingInterceptor.java:109)
    at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:157)
    at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:190)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
    at okhttp3.RealCall.access$100(RealCall.java:30)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Exception in thread "OkHttp Dispatcher" java.lang.NoSuchMethodError: okhttp3.internal.Platform.log(Ljava/lang/String;)V
    at okhttp3.logging.HttpLoggingInterceptor$Logger$1.log(HttpLoggingInterceptor.java:109)
    at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:157)
    at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:190)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
    at okhttp3.RealCall.access$100(RealCall.java:30)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

org.mockito.exceptions.base.MockitoException: 
No argument value was captured!
You might have forgotten to use argument.capture() in verify()...
...or you used capture() in stubbing but stubbed method was not called.
Be aware that it is recommended to use capture() only with verify()

Examples of correct argument capturing:
    ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
    verify(mock).doSomething(argument.capture());
    assertEquals("John", argument.getValue().getName());

Aucun commentaire:

Enregistrer un commentaire