Skip to content

refactor: replace repetitive command/query integration tests with unit tests #187

@andreasgrill

Description

@andreasgrill

Summary

The ~85 command and ~13 query integration tests in src/test/kotlin/.../it/command/ and src/test/kotlin/.../it/query/ are highly repetitive. Each follows an identical two-coroutine template (Mosquitto container + simulated backend) but only differs in the specific command/event types, topic constants, and 2-3 assertion lines. ~90% of each test file is shared boilerplate.

The production code under test (extension functions) are thin 3-5 line wrappers around sendCommandAsync, so the MQTT transport, command-event correlation, and login flow are tested redundantly ~100 times.

Proposed Changes

Keep as integration tests (8-9 tests)

  • ConnectAndLoginTest — login/logout lifecycle, unauthorized login
  • MqttConnectionLostTest — connection loss callback
  • ListenerTest — listener registration/unregistration
  • DelayUntilCloseTest — lifecycle mechanism
  • SubscribedTopicsTest — topic tracking
  • QueryStreamTest — paginated query streaming
  • One representative single-event command (e.g. LockMediumTest)
  • One representative multi-event command (e.g. ChangeAuthorizationProfileTest)
  • One representative query (e.g. QueryCalendarTest)

Replace with unit tests (~80+ tests)

For each removed integration test, add lightweight unit tests following the existing encodingDecoding/ pattern:

  1. Command serialization: construct *Mapi object → serialize → assert JSON
  2. Event deserialization: parse event JSON → assert typed fields
  3. (Optional) Topic constant verification via parameterized test

Keep as-is

  • ExecuteACommandAndSimulateDifferentResultScenarios (already a mocked unit test covering error paths, optional/required events, event ordering)
  • All existing encodingDecoding/ unit tests
  • All serializer and filter unit tests

Benefits

  • Drastically reduced CI time (no Docker container per cookie-cutter test)
  • Less flakiness from testcontainers/MQTT broker
  • Easier maintenance — adding a new command only requires a small unit test, not an 80-line integration test
  • Same regression coverage

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions