Mockk
mocking library for Kotlin
Install / Use
/learn @mockk/MockkREADME
Getting started
All you need to get started is just to add a dependency to MockK library.
Gradle/Maven dependency
<table> <thead><tr><th>Approach</th><th>Instruction</th></tr></thead> <tr> <td><img src="doc/gradle.png" alt="Gradle"/></td> <td> <pre> testImplementation "io.mockk:mockk:${mockkVersion}" </pre> </td> </tr> <tr> <td><img src="doc/gradle.png" alt="Gradle"/> (Kotlin DSL)</td> <td> <pre>testImplementation("io.mockk:mockk:${mockkVersion}")</pre> </td> </tr> <tr> <td><img src="doc/maven.png" alt="Maven"/></td> <td> <pre> <dependency> <groupId>io.mockk</groupId> <artifactId>mockk-jvm</artifactId> <version>${mockkVersion}</version> <scope>test</scope> </dependency> </pre> </td> </tr> <tr> <td><a href="ANDROID.html"><img align="top" src="doc/robot-small.png" height="20" alt="android"/> Unit</a></td> <td> <pre> testImplementation "io.mockk:mockk-android:${mockkVersion}" testImplementation "io.mockk:mockk-agent:${mockkVersion}" </pre> </td> </tr> <tr> <td><a href="ANDROID.html"><img align="top" src="doc/robot-small.png" height="20" alt="android"/> Instrumented</a></td> <td> <pre> androidTestImplementation "io.mockk:mockk-android:${mockkVersion}" androidTestImplementation "io.mockk:mockk-agent:${mockkVersion}" </pre> </td> </tr> </table>DSL examples
Simplest example. By default mocks are strict, so you need to provide some behaviour.
val car = mockk<Car>()
every { car.drive(Direction.NORTH) } returns Outcome.OK
car.drive(Direction.NORTH) // returns OK
verify { car.drive(Direction.NORTH) }
confirmVerified(car)
See the "Features" section below for more detailed examples.
BDD style (optional)
For teams using Behavior-Driven Development, MockK provides BDD-style aliases
testImplementation "io.mockk:mockk:${mockkVersion}"
testImplementation "io.mockk:mockk-bdd:${mockkVersion}"
androidTestImplementation "io.mockk:mockk-android:${mockkVersion}"
androidTestImplementation "io.mockk:mockk-bdd-android:${mockkVersion}"
BDD aliases
| Standard MockK | BDD style |
|----------------|-----------|
| every { ... } | given { ... } |
| coEvery { ... } | coGiven { ... } |
| verify { ... } | then { ... } |
| coVerify { ... } | coThen { ... } |
Spring support
- springmockk introduced in official Spring Boot Kotlin tutorial
Quarkus support
- quarkus-mockk adds support for mocking beans in Quarkus. Documentation can be found here
Kotlin version support
From version 1.13.0 MockK supports Kotlin 1.4 and higher
Known issues
- PowerMock needs a workaround to run together with MockK #79. (not sure after workaround if it is generally usable or not, please somebody report it)
- Inline functions cannot be mocked: see the discussion on this issue
- Spies,
mockkStaticmay not work on JDK 16+;InaccessibleObjectException/IllegalAccessException: read more here - Using a spy with a suspending function will give unexpected test results
Table of contents:
- auto-gen TOC: {:toc}
Examples, guides & articles
Kotlin Academy articles <img src="https://cdn-images-1.medium.com/letterbox/47/47/50/50/1*FUXqI88mttV_kV8aTrKjOg.png?source=logoAvatar-1f9f77b4b3d1---e57b304801ef" width="20px" />
Check the series of articles "Mocking is not rocket science" at Kt. Academy describing MockK from the very basics of mocking up to description of all advanced features.
-
(Video) Use verify in MockK to validate function calls on mocked object
-
KotlinConf 2018 - Best Practices for Unit Testing in Kotlin by Philipp Hauer
-
kotlin-fullstack-sample uses MockK project covered with tests
-
Habrahabr article (RU)
Japanese guides and articles
- Documentation translation to Japanese
- Unraveling MockK's black magic / MockKの「黒魔術」を解明する (JP, but readable through chrome translator)
Chinese guides and articles
- 用 Kotlin + Mockito 寫單元測試會碰到什麼問題?
- MockK 功能介紹:mockk, every, Annotation, verify
- MockK 功能介紹:Relaxed Mocks, 再談 Verify, Capture
- 如何測試 Static Method, Singleton
Korean guides and articles
Features
Annotations
You can use annotations to simplify the creation of mock objects:
class TrafficSystem {
lateinit var car1: Car
lateinit var car2: Car
lateinit var car3: Car
}
class CarTest {
@MockK
lateinit var car1: Car
@RelaxedMockK
lateinit var car2: Car
@MockK(relaxUnitFun = true)
lateinit var car3: Car
@SpyK
var car4 = Car()
@InjectMockKs
var trafficSystem = TrafficSystem()
@Before
fun setUp() = MockKAnnotations.init(this, relaxUnitFun = true) // turn relaxUnitFun on for all mocks
@Test
fun calculateAddsValues1() {
// ... use car1, car2, car3 and car4
}
}
Injection first tries to match properties by name, then by class or superclass.
Check the lookupType parameter for customization.
Properties are injected even if private is applied. Constructors for injection are selected from the biggest
number of arguments to lowest.
@InjectMockKs by default injects only lateinit vars or vars that are not assigned.
To change this, use overrideValues = true. This would assign the value even if it is already initialized somehow.
To inject vals, use injectImmutable = true. For a shorter notation use @OverrideMockKs which does the same as
@InjectMockKs by default, but turns these two flags on.
@InjectMockKs dependency order
If multiple @InjectMockKs properties depend on each other via constructor parameters, initialization order matters.
By default, MockK processes them in reflection order; to resolve dependencies deterministically, enable dependency
order:
@Before
fun setUp() = MockKAnnotations.init(this, useDepende
