[JAVA] If you want to use Mockito with Kotlin, use mockito-kotlin

Please note that this article does not describe how to use Mockito itself. Contains a lot of descriptions for Android.

Problems that occur when used as it is

If you use Mockito as it is in Kotlin, you will get the following code.

val sharedPreferences = mock(SharedPreferences::class.java)
val editor = mock(SharedPreferences.Editor::class.java, RETURNS_DEEP_STUBS)

`when`(sharedPreferences.edit()).thenReturn(editor)
`when`(editor.commit()).thenReturn(true)
`when`(editor.putString(anyString(), anyString())).thenReturn(editor)

The code above is a code to mock Android's SharedPreferences. sharedPreferences.edit () returns a more mocked Editor, allowing you to use commit () and putString ().

The mock () method that creates the mock object is okay, but the part of the when () method that determines the behavior of the mock object is surrounded by backticks, which is very hard to see.

This is a phenomenon that occurs because the word when is a reserved word in Kotlin and needs to be escaped by backticks.

Of course, there is no problem as it is, but this time it is a library that makes the code part of this mock more like Kotlin, [** mockito-kotlin **](https://github.com/nhaarman/mockito- I would like to use kotlin).

environment

Add dependency

Add library references in each way, such as Gradle or Maven.

//testImplementation is adapted to the environment
testImplementation "com.nhaarman:mockito-kotlin:1.5.0"

How to use

Creating a mock object

Instead of passing the class as an argument, it will be specified by generics.

val sharedPreferences = mock<SharedPreferences> {}

The options passed in the second and subsequent arguments will continue to be described in the method arguments.

val editor = mock<SharedPreferences.Editor>(defaultAnswer = RETURNS_DEEP_STUBS) { }

All the contents of withSettings () can also be passed as arguments.

//The arguments that can be used are as follows(1.5.0 present)
extraInterfaces: Array<KClass<out Any>>? = null
name: String? = null
spiedInstance: Any? = null
defaultAnswer: Answer<Any>? = null
serializable: Boolean = false
serializableMode: SerializableMode? = null
verboseLogging: Boolean = false
invocationListeners: Array<InvocationListener>? = null
stubOnly: Boolean = false
useConstructor: Boolean = false
outerInstance: Any? = null
stubbing: KStubbing<T>.(T) -> Unit

Specifying the behavior of mock objects

Do not use when, but describe it inside the function argument{}when creating a mock. ʻOn {method to mock ()} specifies the method to mock the behavior, followed by doReturn, doAnswer, doThrow`. The code below is equivalent to the Mockito code introduced at the beginning of the article.

val editor = mock<SharedPreferences.Editor>(defaultAnswer = RETURNS_DEEP_STUBS) {
    on { commit() } doReturn true
    on { putString(anyString(), anyString()) } doReturn it
}
val sharedPreferences = mock<SharedPreferences> {
    on { edit() } doReturn editor
}

//Below is the code at the beginning of the article
val sharedPreferences = mock(SharedPreferences::class.java)
val editor = mock(SharedPreferences.Editor::class.java, RETURNS_DEEP_STUBS)

`when`(sharedPreferences.edit()).thenReturn(editor)
`when`(editor.commit()).thenReturn(true)
`when`(editor.putString(anyString(), anyString())).thenReturn(editor)

doReturn

The value written continuously will be the return value of the method to be mocked. If the return value is void or ʻUnit, there is no problem if you return ʻUnit.

val stringMock = mock<String> {
    on { toString() } doReturn "mocked"
}
stringMock.toString() // => "mocked"

doAnswer

Write a function that takes a mocked object as a receiver and returns the type that the method is supposed to return. It's like let.

val stringMock = mock<String> {
    on { toString() } doAnswer { "mocked" + it.hashCode() }
}
stringMock.toString() // => "mocked[Numbers]"

doThrow

Throw the exception you wrote in succession.

val stringMock = mock<String> {
    on { toString() } doThrow RuntimeException()
}
stringMock.toString() // => RuntimeException

in conclusion

In the part of specifying the argument of the method to mock, you can use ʻany () and ʻarg That () as well as Mockito, so I think that the basics will not be a problem. For other writing methods, it is easy to understand by looking at the Wiki on Github and the test code, so if you do not know how to write it, you should look at it.

Wiki: https://github.com/nhaarman/mockito-kotlin/wiki/Mocking-and-verifying Test code: https://github.com/nhaarman/mockito-kotlin/tree/2.x/tests/src/test/kotlin/test

Recommended Posts

If you want to use Mockito with Kotlin, use mockito-kotlin
If you dare to compare Integer with "==" ...
If you want to use Oracle JDK 11 from September (add Amazon Corretto)
If you want to make a zip file with Ruby, it's rubyzip.
[Swift] If you want to use a URL that includes Japanese, use addingPercentEncoding.
If you want to modify database columns etc.
You use context to use MDC with Spring WebFlux
I want to use java8 forEach with index
When you want to use the method outside
I want to use Clojure's convenient functions in Kotlin
If you want to separate Spring Boot + Thymeleaf processing
I want to transition screens with kotlin and java!
If you want to recreate the instance in cloud9
If you use SQLite with VSCode, use the extension (how to see the binary file of sqlite3)
Code to use when you want to process Json with only standard library in Java
How to use trained model of tensorflow2.0 with Kotlin / Java
If you want to study programming at university, go to Australia
[# 3 Java] Read this if you want to study Java! ~ Carefully selected ~
I want to make a list with kotlin and java!
I want to make a function with kotlin and java!
When you want to explicitly write OR or AND with ransack
I want to implement various functions with kotlin and java!
docker-compose.yml when you want to keep mysql running with docker
lombok.config when you want to pass @Qualifier to @RequiredArgsConstructor with lombok
Delegate is convenient to use when you want to reuse parts
What to do if you can't use the rails command
You are required to use winpty with docker exec [Windows]
[PostgreSQL] If you want to delete the Rails app, delete the database first!
I want to use FormObject well
I want to return to the previous screen with kotlin and java!
If you want to include the parent class in Lombok's @builder
If you want to change the Java development environment from Eclipse
What to do if you get angry with OpenSSL with pyenv install
If you want to mock a method in RSpec, you should use the allow method for mock and the singleton method.
Practice to use when you want to execute different processing groups serially
[Rails] What to do if you can't get parameters with form_with
Summary of means when you want to communicate with HTTP on Android
If you want to dynamically embed values & add text to attribute values in Thymeleaf 3
I want you to use Enum # name () for the Key of SharedPreference
How to use BootStrap with Play Framework
[Rails] How to use rails console with docker
Basic Rails commands you want to learn
I want to use @Autowired in Servlet
What to do if you install Ubuntu
What to do if you have enabled Use the WSL2 based engine in Docker Desktop with insufficient WSL2 installation
How to make @Transactional work that does not work if you use it incorrectly
You may not want to use the remove method in ArrayList very often
If you are using Android Room and want to change the column definition
I want you to use Scala as Better Java for the time being
[Eclipse] I want to use the completion function, but I want to manage to confirm the completion with spaces.
[Spring Boot] If you use Spring Boot, it was convenient to use a lot of util.
If you throw null to Servlet with ajax, it will be converted to blank ""
How to mock each case with Mockito 1x
I want to test Action Cable with RSpec test
How to use built-in h2db with spring boot
With Tomcat you can use placeholders ($ {...}) in web.xml
When you want to bind InputStream in JDBI3
What to do if you push incorrect information
[Swift] Use nonzeroBitCount when you want popcnt in Swift
Getting started with Kotlin to send to Java developers
Super easy way to use enum with JSP