Mocking is not rocket science: Basics

Oleksiy Pylypenko
Kt. Academy
Published in
3 min readJan 10, 2018

Mocking is a technique to make testing code readable and maintainable. In three consequent articles, I would like to show the basics, features, and quirks of the MockK library. It is a new open-source library (github repository) focused on making mocking in Kotlin great.

Technique used in this article is stubbing, not mocking. This are two similar and often confused terms. Read more about it here.

The main point to have stubs or mocks is to isolate testing one component, which is called System Under Test, from their Dependent-On Components.

The System Under Test (SUT) refers to a system that is being tested for correct operation.

Depended On Component (DOC), is a collaborator, component that is required by SUT to fulfil its duties

The basic idea is to wire SUT to mocked components instead of a Dependent-On Component.

Visualization of System Under Test with two mocked Depended On Component

Or in Kotlin:

class Dependency1(val value1: Int)
class Dependency2(val value2: String)

class SystemUnderTest(
val dependency1: Dependency1,
val dependency2: Dependency2
)

Now, for example, we want to add following function to SUT:

fun calculate() = 
dependency1.value1 + dependency2.value2.toInt()

And test it:

@Test
fun calculateAddsValues() {
val doc1 = mockk<Dependency1>()
val doc2 = mockk<Dependency2>()

every { doc1.value1 } returns 5
every { doc2.value2 } returns "6"

val
sut = SystemUnderTest(doc1, doc2)

assertEquals(11, sut.calculate())
}

Let me explain every line.

val doc1 = mockk<Dependency1>()

Creates a mock object with type Dependency1. This object is a replacement for first Depdendent-On Component of a SUT.

val doc2 = mockk<Dependency2>()

Basically the same, but for Dependency2 DOC.

every { doc1.value1 } returns 5

Provides expected behavior for getter of value1 property. This means we expect that when getter is called the value returned is 5.

every { doc2.value2 } returns "6"

The same for doc2 dependency. We expect value2 to return string “6”.

val sut = SystemUnderTest(doc1, doc2)

Initializes SUT with our mocked DOCs.

assertEquals(11, sut.calculate())

While executing calculate function, mocked components are called and expected behaviors are executed. After that, we verify that result of executing a function with dependencies is correct.

That is basically it. We replaced the dependency with a mock.

Why is this valuable? In this simplified example, it is not so obvious. After all just providing dependent components would test our SUT as well:

@Test
fun calculateAddsValues() {
val doc1 = Dependency1(5)
val doc2 = Dependency2("6")

val sut = SystemUnderTest(doc1, doc2)

assertEquals(11, sut.calculate())
}

That is true. Benefits appear when Dependent-On Component depends on complex configuration and other components. And usually, that is the case. Everything is wired and require other dependencies.

That it for basics. Next article covers setting Dependent-On Component expected behavior and behavior verification.

Clap to say “thank you” and to help others find this article.

Next article about unit testing with MockK will be published next week. Don’t miss it. Subscribe to publication and author’s channel.

--

--