简体   繁体   中英

How to verify a mock interface in a test method using KotlinTest library?

I have an interface that communicates with my presenter who checks whether the fields of a form are valid.

My interface is:

interface MainView {
  fun showMessage(data: LoginEntity)
  fun showEmailError()
  fun showPasswordError()
}

My method in the presenter is like that:

fun sendForm(loginData: LoginDataPresentation, view: MainView) {
   if (isValid()) {
     view.showMessage(mapData(loginData))
   } else if (isValidPassword()) {
     view.showPasswordError()
   } else {
     view.showEmailError()
   }
}

My test class with KotlinTest:

class LoginPresentationKtTest : StringSpec() {

  init {
    "given a bunch of Login Data should be matched successfully" {
       forAll(EmailGenerator(), PasswordGenerator(), { email: String, password: String ->

         val loginData: LoginDataPresentation(email, password)

         val mockMainView = mockMainView()

         sendForm(loginData, mockMainView())

       })
    }
  }

  private fun mockMainView(): MainView {
    //How to mock?????
  }
}

Using the KotlinTest library, is there any way to verify that the call to the showMessage method of the MainView class is done provided that the email and password generated is always correct? Is it possible to use a mock library like mockito?


With the response of the user @mkobit, the following modification can be made using Mockito-Kotlin, with which the test would be as follows:

class LoginPresentationKtTest : StringSpec() {
 init {
   "given a bunch of Login Data should be matched successfully" {
     forAll(EmailGenerator(), PasswordGenerator(), { email: String, password: String ->

       val loginData = LoginDataPresentation(email, password)

       val mockMainView = Mockito.mock(MainView::class.java)

       sendForm(loginData, mockMainView)

       verify(mockMainView).showMessage()
       true
     })
   }
 }
}

At each execution of the loop, it will be checked if the verify () function has been called. If the execution flow is the expected one, it will proceed to the next execution of the loop. If the verify () function fails, an error will occur in the console indicating that the test has failed.

Is there any better solution?

You mentioned Mockito, so I'll show you can example. I'm going to also use the nhaarman/mockito-kotlin library that makes it more expressive and easier to use in Kotlin.

import com.nhaarman.mockito_kotlin.mock

val mockMainView: MainView = mock()

This is basically equivalent to val mockMainView = Mockito.mock(MainView::class.java) from Mockito. In Kotlin, we can get a more concise and compact code due to some of its features.

If you want to do some stubbing (like return values, exceptions, etc.) you could use the whenever ( Mockito.when(T methodCall) ) API. See the documentation for details . I'm going to skip that for now.

So, now you would call for method:

sendForm(loginData, mockMainView)

Then, you can perform verification. Using mockito-kotlin method verify ( Mockito.verify(T mock) ) the behavior.

import com.nhaarman.mockito_kotlin.verify

verify(mockMainView).showPasswordError()
verify(mockMainView).showEmailError()

Using any() ( Mockito.any(Class<T> type) ) to not just verify method is called with any value.

import com.nhaarman.mockito_kotlin.any

verify(mockMainView).showMessage(any())

There is support for other argument matchers if you want to be more explicit with what is being passed in.

Note that Mockito also supports opt-in mocking of final classes/methods . The example for Gradle would be something like adding a file to src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker with the contents of mock-maker-inline .

References:

  1. Mockito Javadoc
  2. mockito-kotlin Wiki documentation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM