Problem
CWService depends on RadioController directly. To unit-test CWService, we had to make 3 methods virtual on RadioController (isConnected, setCWSpeed, getCWSpeedRange) and mock via inheritance. This works but:
- Performance:
MockRadioForCW inherits RadioController which starts a worker thread on construction. Even with a shared fixture, the CW test takes 1.52s for 11 trivial tests — almost all of that is thread start/stop overhead.
- Coupling:
CWService only needs 3 methods but inherits the entire RadioController surface area (connect, disconnect, frequency, band, mode, PTT, RIT, XIT, split, etc.).
- Fragility: Adding new
RadioController constructor side effects will silently slow down or break CW tests.
Proposed Fix
Extract a narrow interface:
class ICWRadio {
public:
virtual ~ICWRadio() = default;
virtual bool isConnected() const = 0;
virtual void setCWSpeed(int wpm) = 0;
virtual void getCWSpeedRange(int& minWpm, int& maxWpm) const = 0;
};
RadioController implements ICWRadio
CWService depends on ICWRadio* instead of RadioController*
- Test mock implements
ICWRadio directly — no thread, no overhead
- Remove
virtual from the 3 RadioController methods (no longer needed)
Current Workaround
Comment in RadioController.h line 42-43 documents the technical debt:
// Note: isConnected, setCWSpeed, getCWSpeedRange are virtual to allow test mocking.
// Ideally CWService would depend on a narrow interface, not RadioController directly.
Shared test fixture in test_cw_service.cpp mitigates the performance issue (6.5s → 1.52s).
Acceptance Criteria
Problem
CWServicedepends onRadioControllerdirectly. To unit-testCWService, we had to make 3 methods virtual onRadioController(isConnected,setCWSpeed,getCWSpeedRange) and mock via inheritance. This works but:MockRadioForCWinheritsRadioControllerwhich starts a worker thread on construction. Even with a shared fixture, the CW test takes 1.52s for 11 trivial tests — almost all of that is thread start/stop overhead.CWServiceonly needs 3 methods but inherits the entireRadioControllersurface area (connect, disconnect, frequency, band, mode, PTT, RIT, XIT, split, etc.).RadioControllerconstructor side effects will silently slow down or break CW tests.Proposed Fix
Extract a narrow interface:
RadioControllerimplementsICWRadioCWServicedepends onICWRadio*instead ofRadioController*ICWRadiodirectly — no thread, no overheadvirtualfrom the 3RadioControllermethods (no longer needed)Current Workaround
Comment in
RadioController.hline 42-43 documents the technical debt:Shared test fixture in
test_cw_service.cppmitigates the performance issue (6.5s → 1.52s).Acceptance Criteria
ICWRadiointerface extractedCWServicedepends onICWRadio*RadioControllerimplementsICWRadioICWRadiodirectly (no thread overhead)virtualremoved fromRadioControllermethods