anchor.diff:    });
   }
   
  -class MockHotRunner extends Mock implements HotRunner {}
  -class MockHotRunnerFactory extends Mock implements HotRunnerFactory {}
  -class MockPortForwarder extends Mock implements DevicePortForwarder {}
  +class FakeHotRunner extends Fake implements HotRunner {
  +  Future<int> Function(Completer<DebugConnectionInfo>, Completer<void>, bool, bool) onAttach;
  +
  +  @override
  +  bool exited = false;
  +
  +  @override
  +  bool isWaitingForObservatory = true;
  +
  +  @override
  +  Future<int> attach({
  +    Completer<DebugConnectionInfo> connectionInfoCompleter,
  +    Completer<void> appStartedCompleter,
  +    bool allowExistingDdsInstance = false,
  +    bool enableDevTools = false,
  +  }) {
  +    return onAttach(connectionInfoCompleter, appStartedCompleter, allowExistingDdsInstance, enableDevTools);
  +  }
  +}
  +
  +class FakeHotRunnerFactory extends Fake implements HotRunnerFactory {
  +  HotRunner hotRunner;
  +  String dillOutputPath;
  +  String projectRootPath;
  +  List<FlutterDevice> devices;
  +
  +  @override
  +  HotRunner build(
  +    List<FlutterDevice> devices, {
  +    String target,
  +    DebuggingOptions debuggingOptions,
  +    bool benchmarkMode = false,
  +    File applicationBinary,
  +    bool hostIsIde = false,
  +    String projectRootPath,
  +    String packagesFilePath,
  +    String dillOutputPath,
  +    bool stayResident = true,
  +    bool ipv6 = false,
  +    FlutterProject flutterProject,
  +  }) {
  +    this.devices = devices;
  +    this.dillOutputPath = dillOutputPath;
  +    this.projectRootPath = projectRootPath;
  +    return hotRunner;
  +  }
  +}
  +
  +class RecordingPortForwarder implements DevicePortForwarder {
  +  RecordingPortForwarder([this.hostPort]);
  +
  +  int devicePort;
  +  int hostPort;
  +
  +  @override
  +  Future<void> dispose() async { }
  +
  +  @override
  +  Future<int> forward(int devicePort, {int hostPort}) async {
  +    this.devicePort = devicePort;
  +    this.hostPort ??= hostPort;
  +    return this.hostPort;
  +  }
  +
  +  @override
  +  List<ForwardedPort> get forwardedPorts => <ForwardedPort>[];
  +
  +  @override
  +  Future<void> unforward(ForwardedPort forwardedPort) async { }
  +}
   
   class StreamLogger extends Logger {
     @override
  
positive.code:       });
  
        testUsingContext('accepts filesystem parameters', () async {
          when(device.getLogReader(includePastLogs: anyNamed('includePastLogs')))
            .thenAnswer((_) {
              // Now that the reader is used, start writing messages to it.
              fakeLogReader.addLine('Foo');
              fakeLogReader.addLine('Observatory listening on http://127.0.0.1:$devicePort');
              return fakeLogReader;
            });
          testDeviceManager.addDevice(device);
  
          const String filesystemScheme = 'foo';
  
negative.code:       });
  
        testUsingContext('exits when ipv6 is specified and debug-port is not', () async {
          testDeviceManager.addDevice(device);
  
          final AttachCommand command = AttachCommand();
  