傳統單元測試擅長驗證「輸入-輸出」與「狀態變更」,卻難以斷言「多個對象協作時的方法調用順序」。例如 Coordinator 需依次調用 Greeter.sayHello() → Sender.sendFirst() → Sender.sendSecond() → Greeter.sayGoodbye(),若重構引入多線程或信號量,順序極易被打亂。
核心思想:注入同一 Recorder 實例到所有協作對象,每個方法入口調用 recorder.record("methodName()")。測試時只需比對 recorder.playBack() 與期望字符串:
public class Recorder {
private StringBuffer tape = new StringBuffer();
public void record(String s) { tape.append(s); }
public String playBack() { return tape.toString(); }
}
測試代碼極其簡潔:
Recorder r = new Recorder();
Coordinator c = new Coordinator(new Sender(r), new Greeter(r));
c.start(); c.join();
assertEquals("sayHello();sendFirstMessage();sendSecondMessage();sayGoodbye();", r.playBack());
equals(),測試基建成本高。toString() 用於序列斷言,兼顧兩全。Recorder 模式不限於順序驗證:分布式系統中可記錄網絡消息序列驗證協議不變量;GUI 測試中可記錄用戶操作與響應序列。它將測試粒度從「單一組件」擴展至「組件協作集合」,填補了單元測試與集成測試之間的空白。