Testing with MockHomeApi

MockHomeApi lets Kotlin tests create, change, and read data in memory without contacting a server. Use it for application flows supported by the mock.

Instantiating

Create a fresh instance for each test and set its base URL before making API calls:

import com.russhwolf.settings.MapSettings
import no.solibo.oss.sdk.api.MockHomeApi

val mockApi = MockHomeApi(fingerprinter, device, settings = MapSettings())
mockApi.setInitialBaseUrl("https://api.example.com")

MapSettings provides an in-memory settings store. Supply your test implementations of Fingerprinter and DeviceManager, or use these minimal stubs:

Minimal test stubs

import no.solibo.oss.sdk.api.gen.models.SoliboAuthentication
import no.solibo.oss.sdk.auth.DeviceManager
import no.solibo.oss.sdk.auth.Fingerprinter

private val fingerprinter = object : Fingerprinter {
    override fun print(username: String) = "fingerprint"
}
private val device = object : DeviceManager {
    override fun store(result: SoliboAuthentication) {}
    override fun clear(userId: String) {}
    override fun key(username: String): String? = "device-key"
    override fun group(username: String): String? = "device-group"
    override suspend fun token(): String? = "token"
    override suspend fun generateVerification(
        userId: String, password: String, deviceKey: String?, deviceGroupKey: String?
    ): Pair<String, String> = "" to ""
}

Patterns

Create via API, then verify

API calls share state within the same mock instance. For example, in a coroutine test:

import kotlinx.coroutines.test.runTest
import no.solibo.oss.sdk.api.gen.models.CreateTaskCommand
import kotlin.test.Test
import kotlin.test.assertEquals

@Test
fun createsTask() = runTest {
    val mockApi = MockHomeApi(fingerprinter, device, settings = MapSettings())
    mockApi.setInitialBaseUrl("https://api.example.com")

    val created = mockApi.task.createTask(
        1L,
        CreateTaskCommand(title = "My Task", description = "Details"),
    ).body()

    val task = mockApi.task.indexTasks(1L).body().items.single()
    assertEquals(created.id, task.id)
    assertEquals("My Task", task.title)
}

The backend property

Seed specific fixtures through mockApi.backend maps, such as tasks, companies, or sections:

import no.solibo.oss.sdk.api.gen.models.Task

mockApi.backend.tasks[999L] = Task(
    id = 999L,
    companyId = 1L,
    title = "Pre-seeded",
    log = emptyList(),
)

Then read or change that resource through the API as usual.

Prefilling

Every new mock includes companies 1 and 2 and the user mockuser.

  • Pass prefill = true to MockHomeApi for sample resources in company 1, or call mockApi.backend.prefillResources() later.
  • Call mockApi.backend.reset() to clear state and captured requests and restore the default companies and user. Call prefillResources() again if needed.

Fallback behaviour

Some unseeded resources are created automatically. For example, showCompany(42L) supplies a mock company, and an empty indexSection(companyId) creates a sample section.

An unhandled route returns HTTP 200 with {}, which may fail to deserialize. A successful mock call therefore does not prove that the real backend accepts the request or enforces its rules.

Inspecting captured requests

Use mockApi.backend.capturedRequests to inspect the HTTP requests made by your test:

mockApi.backend.capturedRequests.clear()
mockApi.task.createTask(1L, CreateTaskCommand(title = "T"))

val request = mockApi.backend.capturedRequests.single()
assertEquals("POST", request.method.value)

Solibo AS