### Question:
RssiScanMatcher implements ScanMatcher { @Override public ObservableTransformer<ScanData, ScanData> match() { return scanDataStream -> scanDataStream .doOnSubscribe(disposable -> matches.clear()) .compose(serviceScanMatcher.match()) .doOnNext(scanData -> { synchronized (syncRoot) { matches.put(scanData.getBluetoothDevice().getAddress(), scanData); } }) .delay(matchDelayMs, TimeUnit.MILLISECONDS) .filter(match -> { synchronized (syncRoot) { for (ScanData other : matches.values()) { if (other.getBluetoothDevice().getAddress().contentEquals( match.getBluetoothDevice().getAddress())) { continue; } if (other.getRssi() > match.getRssi()) { return false; } } return true; } }); } RssiScanMatcher(ServiceScanMatcher serviceScanMatcher);  RssiScanMatcher(ServiceScanMatcher serviceScanMatcher, int matchDelayMs); @Override ObservableTransformer<ScanData, ScanData> match(); @Override boolean equals(Object o); @Override int hashCode(); static final int DEFAULT_MATCH_DELAY_MS; }### Answer:
@Test public void match_none() { ObservableTransformer<ScanData, ScanData> serviceMatch = scanData -> scanData.filter(sd -> false); when(serviceScanMatcher.match()).thenReturn(serviceMatch); scanDataTestObserver = scanDataRelay .compose(rssiScanMatcher.match()) .test(); scanDataRelay.accept(scanData1); scanDataRelay.accept(scanData2); scanDataTestObserver.assertEmpty(); }
@Test public void match_closest() { ObservableTransformer<ScanData, ScanData> serviceMatch = scanData -> scanData.filter(sd -> true); when(serviceScanMatcher.match()).thenReturn(serviceMatch); scanDataTestObserver = scanDataRelay .compose(rssiScanMatcher.match()) .test(); when(scanData1.getRssi()).thenReturn(-60); when(scanData2.getRssi()).thenReturn(-50); scanDataRelay.accept(scanData1); testScheduler.advanceTimeBy(500, TimeUnit.MILLISECONDS); scanDataRelay.accept(scanData2); testScheduler.advanceTimeBy( RssiScanMatcher.DEFAULT_MATCH_DELAY_MS + 500, TimeUnit.MILLISECONDS); scanDataTestObserver.assertValue(scanData2); }