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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions