[flutter_tools] fully remove mocks from resident_runner_test.dart (#84591)

diff --git a/packages/flutter_tools/test/general.shard/resident_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
index 28186b5..8bd6b62 100644
--- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
@@ -35,8 +35,8 @@
 import 'package:flutter_tools/src/version.dart';
 import 'package:flutter_tools/src/vmservice.dart';
 import 'package:meta/meta.dart';
-import 'package:mockito/mockito.dart';
 import 'package:package_config/package_config.dart';
+import 'package:test/fake.dart';
 import 'package:vm_service/vm_service.dart' as vm_service;
 
 import '../src/common.dart';
@@ -142,10 +142,10 @@
 
 void main() {
   Testbed testbed;
-  MockFlutterDevice mockFlutterDevice;
-  FakeDevFS mockDevFS;
+  FakeFlutterDevice flutterDevice;
+  FakeDevFS devFS;
   ResidentRunner residentRunner;
-  FakeDevice mockDevice;
+  FakeDevice device;
   FakeVmServiceHost fakeVmServiceHost;
 
   setUp(() {
@@ -157,7 +157,7 @@
         ..writeAsStringSync('ABC');
       residentRunner = HotRunner(
         <FlutterDevice>[
-          mockFlutterDevice,
+          flutterDevice,
         ],
         stayResident: false,
         debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
@@ -165,48 +165,13 @@
         devtoolsHandler: createNoOpHandler,
       );
     });
-    mockFlutterDevice = MockFlutterDevice();
-    mockDevice = FakeDevice();
-    mockDevFS = FakeDevFS();
-    // FlutterDevice Mocks.
-    when(mockFlutterDevice.updateDevFS(
-      invalidatedFiles: anyNamed('invalidatedFiles'),
-      mainUri: anyNamed('mainUri'),
-      target: anyNamed('target'),
-      bundle: anyNamed('bundle'),
-      firstBuildTime: anyNamed('firstBuildTime'),
-      bundleFirstUpload: anyNamed('bundleFirstUpload'),
-      bundleDirty: anyNamed('bundleDirty'),
-      fullRestart: anyNamed('fullRestart'),
-      projectRootPath: anyNamed('projectRootPath'),
-      pathToReload: anyNamed('pathToReload'),
-      dillOutputPath: anyNamed('dillOutputPath'),
-      packageConfig: anyNamed('packageConfig'),
-    )).thenAnswer((Invocation invocation) async {
-      return UpdateFSReport(
-        success: true,
-        syncedBytes: 0,
-        invalidatedSourcesCount: 1,
-      );
-    });
-    when(mockFlutterDevice.devFS).thenReturn(mockDevFS);
-    when(mockFlutterDevice.device).thenReturn(mockDevice);
-    when(mockFlutterDevice.stopEchoingDeviceLog()).thenAnswer((Invocation invocation) async { });
-    when(mockFlutterDevice.observatoryUris).thenAnswer((_) => Stream<Uri>.value(testUri));
-    when(mockFlutterDevice.connect(
-      reloadSources: anyNamed('reloadSources'),
-      restart: anyNamed('restart'),
-      compileExpression: anyNamed('compileExpression'),
-      getSkSLMethod: anyNamed('getSkSLMethod'),
-      allowExistingDdsInstance: anyNamed('allowExistingDdsInstance'),
-    )).thenAnswer((Invocation invocation) async { });
-    when(mockFlutterDevice.setupDevFS(any, any))
-      .thenAnswer((Invocation invocation) async {
-        return testUri;
-      });
-    when(mockFlutterDevice.vmService).thenAnswer((Invocation invocation) {
-      return fakeVmServiceHost?.vmService;
-    });
+    device = FakeDevice();
+    devFS = FakeDevFS();
+    flutterDevice = FakeFlutterDevice()
+      ..testUri = testUri
+      ..vmServiceHost = (() => fakeVmServiceHost)
+      ..device = device
+      .._devFS = devFS;
   });
 
   testUsingContext('ResidentRunner can attach to device successfully', () => testbed.run(() async {
@@ -225,9 +190,6 @@
     final Future<DebugConnectionInfo> connectionInfo = futureConnectionInfo.future;
 
     expect(await result, 0);
-
-    verify(mockFlutterDevice.initLogReader()).called(1);
-
     expect(futureConnectionInfo.isCompleted, true);
     expect((await connectionInfo).baseUri, 'foo://bar');
     expect(futureAppStart.isCompleted, true);
@@ -242,45 +204,21 @@
       listViews,
       setAssetBundlePath,
     ]);
-    final MockResidentCompiler residentCompiler = MockResidentCompiler();
+    final FakeResidentCompiler residentCompiler = FakeResidentCompiler()
+      ..nextOutput = const CompilerOutput('foo', 0 ,<Uri>[]);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
       target: 'main.dart',
       devtoolsHandler: createNoOpHandler,
     );
-    when(mockFlutterDevice.generator).thenReturn(residentCompiler);
-    when(residentCompiler.recompile(
-      any,
-      any,
-      outputPath: anyNamed('outputPath'),
-      packageConfig: anyNamed('packageConfig'),
-      suppressErrors: true,
-      projectRootPath: anyNamed('projectRootPath'),
-      fs: anyNamed('fs'),
-    )).thenAnswer((Invocation invocation) async {
-      return const CompilerOutput('foo', 0 ,<Uri>[]);
-    });
-    when(mockFlutterDevice.runHot(
-      hotRunner: anyNamed('hotRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 0;
-    });
+    flutterDevice.generator = residentCompiler;
 
     expect(await residentRunner.run(enableDevTools: true), 0);
-    verify(residentCompiler.recompile(
-      any,
-      any,
-      outputPath: anyNamed('outputPath'),
-      packageConfig: anyNamed('packageConfig'),
-      suppressErrors: true,
-      projectRootPath: anyNamed('projectRootPath'),
-      fs: anyNamed('fs'),
-    )).called(1);
+    expect(residentCompiler.didSuppressErrors, true);
     expect(fakeVmServiceHost.hasRemainingExpectations, false);
   }));
 
@@ -289,34 +227,18 @@
     globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
       .createSync(recursive: true);
     fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-    final MockResidentCompiler residentCompiler = MockResidentCompiler();
+    final FakeResidentCompiler residentCompiler = FakeResidentCompiler()
+      ..nextOutput = const CompilerOutput('foo', 1 ,<Uri>[]);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
       target: 'main.dart',
       devtoolsHandler: createNoOpHandler,
     );
-    when(mockFlutterDevice.generator).thenReturn(residentCompiler);
-    when(residentCompiler.recompile(
-      any,
-      any,
-      outputPath: anyNamed('outputPath'),
-      packageConfig: anyNamed('packageConfig'),
-      suppressErrors: true,
-      projectRootPath: anyNamed('projectRootPath'),
-      fs: anyNamed('fs'),
-    )).thenAnswer((Invocation invocation) async {
-      return const CompilerOutput('foo', 1 ,<Uri>[]);
-    });
-    when(mockFlutterDevice.runHot(
-      hotRunner: anyNamed('hotRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 0;
-    });
+    flutterDevice.generator = residentCompiler;
 
     expect(await residentRunner.run(), 1);
     // Completing this future ensures that the daemon can exit correctly.
@@ -330,19 +252,14 @@
     fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
     residentRunner = ColdRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(BuildInfo.release),
       target: 'main.dart',
       devtoolsHandler: createNoOpHandler,
     );
-    when(mockFlutterDevice.runCold(
-      coldRunner: anyNamed('coldRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 1;
-    });
+    flutterDevice.runColdCode = 1;
 
     expect(await residentRunner.run(), 1);
     // Completing this future ensures that the daemon can exit correctly.
@@ -356,19 +273,15 @@
     fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
     residentRunner = ColdRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(BuildInfo.release),
       target: 'main.dart',
       devtoolsHandler: createNoOpHandler,
     );
-    when(mockFlutterDevice.runCold(
-      coldRunner: anyNamed('coldRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      throw Exception('BAD STUFF');
-    });
+    flutterDevice.runColdError = Exception('BAD STUFF');
+
 
     expect(await residentRunner.run(), 1);
     // Completing this future ensures that the daemon can exit correctly.
@@ -383,10 +296,11 @@
       listViews,
       setAssetBundlePath,
     ]);
-    final MockResidentCompiler residentCompiler = MockResidentCompiler();
+    final FakeResidentCompiler residentCompiler = FakeResidentCompiler()
+      ..nextOutput = const CompilerOutput('foo', 0 ,<Uri>[]);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       applicationBinary: globals.fs.file('app.apk'),
       stayResident: false,
@@ -394,35 +308,10 @@
       target: 'main.dart',
       devtoolsHandler: createNoOpHandler,
     );
-    when(mockFlutterDevice.generator).thenReturn(residentCompiler);
-    when(residentCompiler.recompile(
-      any,
-      any,
-      outputPath: anyNamed('outputPath'),
-      packageConfig: anyNamed('packageConfig'),
-      projectRootPath: anyNamed('projectRootPath'),
-      fs: anyNamed('fs'),
-      suppressErrors: false,
-    )).thenAnswer((Invocation invocation) async {
-      return const CompilerOutput('foo', 0, <Uri>[]);
-    });
-    when(mockFlutterDevice.runHot(
-      hotRunner: anyNamed('hotRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 0;
-    });
+    flutterDevice.generator = residentCompiler;
 
     expect(await residentRunner.run(enableDevTools: true), 0);
-    verify(residentCompiler.recompile(
-      any,
-      any,
-      outputPath: anyNamed('outputPath'),
-      packageConfig: anyNamed('packageConfig'),
-      suppressErrors: false,
-      projectRootPath: anyNamed('projectRootPath'),
-      fs: anyNamed('fs'),
-    )).called(1);
+    expect(residentCompiler.didSuppressErrors, false);
     expect(fakeVmServiceHost.hasRemainingExpectations, false);
   }));
 
@@ -468,7 +357,7 @@
     ]);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(
@@ -489,9 +378,6 @@
     final Future<DebugConnectionInfo> connectionInfo = futureConnectionInfo.future;
 
     expect(await result, 0);
-
-    verify(mockFlutterDevice.initLogReader()).called(1);
-
     expect(futureConnectionInfo.isCompleted, true);
     expect((await connectionInfo).baseUri, 'foo://bar');
     expect(futureAppStart.isCompleted, true);
@@ -513,20 +399,7 @@
       enableDevTools: true,
     ));
     await futureAppStart.future;
-    when(mockFlutterDevice.updateDevFS(
-      mainUri: anyNamed('mainUri'),
-      target: anyNamed('target'),
-      bundle: anyNamed('bundle'),
-      firstBuildTime: anyNamed('firstBuildTime'),
-      bundleFirstUpload: anyNamed('bundleFirstUpload'),
-      bundleDirty: anyNamed('bundleDirty'),
-      fullRestart: anyNamed('fullRestart'),
-      projectRootPath: anyNamed('projectRootPath'),
-      pathToReload: anyNamed('pathToReload'),
-      invalidatedFiles: anyNamed('invalidatedFiles'),
-      dillOutputPath: anyNamed('dillOutputPath'),
-      packageConfig: anyNamed('packageConfig'),
-    )).thenThrow(vm_service.RPCError('something bad happened', 666, ''));
+    flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, '');
 
     final OperationResult result = await residentRunner.restart(fullRestart: false);
     expect(result.fatal, true);
@@ -557,7 +430,7 @@
       connectionInfoCompleter: futureConnectionInfo,
     ));
     await futureAppStart.future;
-    when(mockFlutterDevice.devFS).thenReturn(null);
+    flutterDevice._devFS = null;
 
     final OperationResult result = await residentRunner.restart(fullRestart: false);
     expect(result.fatal, false);
@@ -581,20 +454,7 @@
       enableDevTools: true,
     ));
     await futureAppStart.future;
-    when(mockFlutterDevice.updateDevFS(
-      mainUri: anyNamed('mainUri'),
-      target: anyNamed('target'),
-      bundle: anyNamed('bundle'),
-      firstBuildTime: anyNamed('firstBuildTime'),
-      bundleFirstUpload: anyNamed('bundleFirstUpload'),
-      bundleDirty: anyNamed('bundleDirty'),
-      fullRestart: anyNamed('fullRestart'),
-      projectRootPath: anyNamed('projectRootPath'),
-      pathToReload: anyNamed('pathToReload'),
-      invalidatedFiles: anyNamed('invalidatedFiles'),
-      dillOutputPath: anyNamed('dillOutputPath'),
-      packageConfig: anyNamed('packageConfig'),
-    )).thenThrow(vm_service.RPCError('something bad happened', kIsolateReloadBarred, ''));
+    flutterDevice.reportError = vm_service.RPCError('something bad happened', kIsolateReloadBarred, '');
 
     final OperationResult result = await residentRunner.restart(fullRestart: false);
     expect(result.fatal, true);
@@ -623,7 +483,7 @@
     ]);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       target: 'main.dart',
@@ -642,20 +502,7 @@
       enableDevTools: true,
     ));
     await futureAppStart.future;
-    when(mockFlutterDevice.updateDevFS(
-      mainUri: anyNamed('mainUri'),
-      target: anyNamed('target'),
-      bundle: anyNamed('bundle'),
-      firstBuildTime: anyNamed('firstBuildTime'),
-      bundleFirstUpload: anyNamed('bundleFirstUpload'),
-      bundleDirty: anyNamed('bundleDirty'),
-      fullRestart: anyNamed('fullRestart'),
-      projectRootPath: anyNamed('projectRootPath'),
-      pathToReload: anyNamed('pathToReload'),
-      invalidatedFiles: anyNamed('invalidatedFiles'),
-      dillOutputPath: anyNamed('dillOutputPath'),
-      packageConfig: anyNamed('packageConfig'),
-    )).thenThrow(vm_service.RPCError('something bad happened', 666, ''));
+    flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, '');
 
     final OperationResult result = await residentRunner.restart(fullRestart: false);
     expect(result.fatal, true);
@@ -696,7 +543,7 @@
     ]);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
@@ -711,22 +558,7 @@
       enableDevTools: true,
     ));
     await futureAppStart.future;
-    when(mockFlutterDevice.updateDevFS(
-      mainUri: anyNamed('mainUri'),
-      target: anyNamed('target'),
-      bundle: anyNamed('bundle'),
-      firstBuildTime: anyNamed('firstBuildTime'),
-      bundleFirstUpload: anyNamed('bundleFirstUpload'),
-      bundleDirty: anyNamed('bundleDirty'),
-      fullRestart: anyNamed('fullRestart'),
-      projectRootPath: anyNamed('projectRootPath'),
-      pathToReload: anyNamed('pathToReload'),
-      invalidatedFiles: anyNamed('invalidatedFiles'),
-      dillOutputPath: anyNamed('dillOutputPath'),
-      packageConfig: anyNamed('packageConfig'),
-    )).thenAnswer((Invocation _) async {
-      return UpdateFSReport(success: true, invalidatedSourcesCount: 0);
-    });
+    flutterDevice.report =  UpdateFSReport(success: true, invalidatedSourcesCount: 0);
 
     final OperationResult result = await residentRunner.restart(fullRestart: false);
 
@@ -785,22 +617,7 @@
       enableDevTools: true,
     ));
     await futureAppStart.future;
-    when(mockFlutterDevice.updateDevFS(
-      mainUri: anyNamed('mainUri'),
-      target: anyNamed('target'),
-      bundle: anyNamed('bundle'),
-      firstBuildTime: anyNamed('firstBuildTime'),
-      bundleFirstUpload: anyNamed('bundleFirstUpload'),
-      bundleDirty: anyNamed('bundleDirty'),
-      fullRestart: anyNamed('fullRestart'),
-      projectRootPath: anyNamed('projectRootPath'),
-      pathToReload: anyNamed('pathToReload'),
-      invalidatedFiles: anyNamed('invalidatedFiles'),
-      dillOutputPath: anyNamed('dillOutputPath'),
-      packageConfig: anyNamed('packageConfig'),
-    )).thenAnswer((Invocation invocation) async {
-      return UpdateFSReport(success: true, invalidatedSourcesCount: 1);
-    });
+    flutterDevice.report =  UpdateFSReport(success: true, invalidatedSourcesCount: 1);
 
     final OperationResult result = await residentRunner.restart(fullRestart: false);
 
@@ -865,29 +682,14 @@
       enableDevTools: true,
     ));
     await futureAppStart.future;
-    when(mockFlutterDevice.updateDevFS(
-      mainUri: anyNamed('mainUri'),
-      target: anyNamed('target'),
-      bundle: anyNamed('bundle'),
-      firstBuildTime: anyNamed('firstBuildTime'),
-      bundleFirstUpload: anyNamed('bundleFirstUpload'),
-      bundleDirty: anyNamed('bundleDirty'),
-      fullRestart: anyNamed('fullRestart'),
-      projectRootPath: anyNamed('projectRootPath'),
-      pathToReload: anyNamed('pathToReload'),
-      invalidatedFiles: anyNamed('invalidatedFiles'),
-      dillOutputPath: anyNamed('dillOutputPath'),
-      packageConfig: anyNamed('packageConfig'),
-    )).thenAnswer((Invocation invocation) async {
-      return UpdateFSReport(success: true, invalidatedSourcesCount: 1);
-    });
+    flutterDevice.report =  UpdateFSReport(success: true, invalidatedSourcesCount: 1);
 
     final OperationResult result = await residentRunner.restart(fullRestart: false);
 
     expect(result.fatal, false);
     expect(result.message, contains('Reload rejected: Failed to hot reload')); // contains error message from reload report.
     expect(result.code, 1);
-    expect(mockDevFS.lastCompiled, null);
+    expect(devFS.lastCompiled, null);
   }));
 
   testUsingContext('ResidentRunner can send target platform to analytics from hot reload', () => testbed.run(() async {
@@ -998,11 +800,11 @@
         },
       ),
     ]);
-    final FakeFlutterDevice flutterDevice =  FakeFlutterDevice(
-      mockDevice,
+    final FakeDelegateFlutterDevice flutterDevice =  FakeDelegateFlutterDevice(
+      device,
       BuildInfo.debug,
       FakeResidentCompiler(),
-      mockDevFS,
+      devFS,
     )..vmService = fakeVmServiceHost.vmService;
     residentRunner = HotRunner(
       <FlutterDevice>[
@@ -1013,7 +815,7 @@
       target: 'main.dart',
       devtoolsHandler: createNoOpHandler,
     );
-    mockDevFS.nextUpdateReport = UpdateFSReport(
+    devFS.nextUpdateReport = UpdateFSReport(
       success: true,
       fastReassembleClassName: 'FOO',
       invalidatedSourcesCount: 1,
@@ -1310,20 +1112,7 @@
       enableDevTools: true,
     ));
     await futureAppStart.future;
-    when(mockFlutterDevice.updateDevFS(
-      mainUri: anyNamed('mainUri'),
-      target: anyNamed('target'),
-      bundle: anyNamed('bundle'),
-      firstBuildTime: anyNamed('firstBuildTime'),
-      bundleFirstUpload: anyNamed('bundleFirstUpload'),
-      bundleDirty: anyNamed('bundleDirty'),
-      fullRestart: anyNamed('fullRestart'),
-      projectRootPath: anyNamed('projectRootPath'),
-      pathToReload: anyNamed('pathToReload'),
-      invalidatedFiles: anyNamed('invalidatedFiles'),
-      dillOutputPath: anyNamed('dillOutputPath'),
-      packageConfig: anyNamed('packageConfig'),
-    )).thenThrow(vm_service.RPCError('something bad happened', 666, ''));
+    flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, '');
 
     final OperationResult result = await residentRunner.restart(fullRestart: true);
     expect(result.fatal, true);
@@ -1348,7 +1137,7 @@
 
     final ResidentRunner otherRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
@@ -1510,7 +1299,7 @@
     fakeVmServiceHost = null;
     residentRunner = ColdRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
@@ -1545,7 +1334,7 @@
     fakeVmServiceHost = null;
     residentRunner = ColdRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
@@ -1635,19 +1424,13 @@
     ]);
     residentRunner = ColdRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'),
       target: 'main.dart',
       devtoolsHandler: createNoOpHandler,
     );
-    when(mockFlutterDevice.runCold(
-      coldRunner: anyNamed('coldRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 0;
-    });
 
     final Future<int> result = residentRunner.attach(enableDevTools: false);
     expect(await result, 0);
@@ -1655,25 +1438,25 @@
 
   testUsingContext('FlutterDevice can exit from a release mode isolate with no VmService', () => testbed.run(() async {
     final TestFlutterDevice flutterDevice = TestFlutterDevice(
-      mockDevice,
+      device,
     );
 
     await flutterDevice.exitApps();
 
-    expect(mockDevice.appStopped, true);
+    expect(device.appStopped, true);
   }));
 
   testUsingContext('FlutterDevice will exit an un-paused isolate using stopApp', () => testbed.run(() async {
     fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
     final TestFlutterDevice flutterDevice = TestFlutterDevice(
-      mockDevice,
+      device,
     );
     flutterDevice.vmService = fakeVmServiceHost.vmService;
 
     final Future<void> exitFuture = flutterDevice.exitApps();
 
     await expectLater(exitFuture, completes);
-    expect(mockDevice.appStopped, true);
+    expect(device.appStopped, true);
     expect(fakeVmServiceHost.hasRemainingExpectations, false);
   }));
 
@@ -1686,19 +1469,14 @@
     globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, vmserviceOutFile: 'foo'),
       target: 'main.dart',
       devtoolsHandler: createNoOpHandler,
     );
-    when(mockFlutterDevice.runHot(
-      hotRunner: anyNamed('hotRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 0;
-    });
+
     await residentRunner.run(enableDevTools: true);
 
     expect(fakeVmServiceHost.hasRemainingExpectations, false);
@@ -1714,7 +1492,7 @@
     globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
@@ -1722,12 +1500,7 @@
       devtoolsHandler: createNoOpHandler,
     );
     residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
-    when(mockFlutterDevice.runHot(
-      hotRunner: anyNamed('hotRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 0;
-    });
+
     await residentRunner.run(enableDevTools: true);
 
     expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill')).readAsString(), 'ABC');
@@ -1742,7 +1515,7 @@
     globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(
@@ -1757,12 +1530,7 @@
       devtoolsHandler: createNoOpHandler,
     );
     residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
-    when(mockFlutterDevice.runHot(
-      hotRunner: anyNamed('hotRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 0;
-    });
+
     await residentRunner.run(enableDevTools: true);
 
     expect(await globals.fs.file(globals.fs.path.join(
@@ -1778,7 +1546,7 @@
     globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(
@@ -1793,12 +1561,7 @@
       devtoolsHandler: createNoOpHandler,
     );
     residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
-    when(mockFlutterDevice.runHot(
-      hotRunner: anyNamed('hotRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 0;
-    });
+
     await residentRunner.run(enableDevTools: true);
 
     expect(await globals.fs.file(globals.fs.path.join(
@@ -1814,7 +1577,7 @@
     globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       dillOutputPath: 'test',
@@ -1823,12 +1586,7 @@
       devtoolsHandler: createNoOpHandler,
     );
     residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
-    when(mockFlutterDevice.runHot(
-      hotRunner: anyNamed('hotRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 0;
-    });
+
     await residentRunner.run(enableDevTools: true);
 
     expect(globals.fs.file(globals.fs.path.join('build', 'cache.dill')), isNot(exists));
@@ -1843,7 +1601,7 @@
     globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(const BuildInfo(
@@ -1856,12 +1614,7 @@
       devtoolsHandler: createNoOpHandler,
     );
     residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
-    when(mockFlutterDevice.runHot(
-      hotRunner: anyNamed('hotRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 0;
-    });
+
     await residentRunner.run(enableDevTools: true);
 
     expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill.track.dill')).readAsString(), 'ABC');
@@ -1876,22 +1629,16 @@
     globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
       target: 'main.dart',
       devtoolsHandler: createNoOpHandler,
     );
-    when(mockFlutterDevice.runHot(
-      hotRunner: anyNamed('hotRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 0;
-    });
 
     await residentRunner.run();
-    expect(mockDevice.disposed, true);
+    expect(device.disposed, true);
   }));
 
   testUsingContext('HotRunner handles failure to write vmservice file', () => testbed.run(() async {
@@ -1903,19 +1650,14 @@
     globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, vmserviceOutFile: 'foo'),
       target: 'main.dart',
       devtoolsHandler: createNoOpHandler,
     );
-    when(mockFlutterDevice.runHot(
-      hotRunner: anyNamed('hotRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 0;
-    });
+
     await residentRunner.run(enableDevTools: true);
 
     expect(testLogger.errorText, contains('Failed to write vmservice-out-file at foo'));
@@ -1931,19 +1673,14 @@
     globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
     residentRunner = ColdRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'),
       target: 'main.dart',
       devtoolsHandler: createNoOpHandler,
     );
-    when(mockFlutterDevice.runCold(
-      coldRunner: anyNamed('coldRunner'),
-      route: anyNamed('route'),
-    )).thenAnswer((Invocation invocation) async {
-      return 0;
-    });
+
     await residentRunner.run(enableDevTools: true);
 
     expect(await globals.fs.file('foo').readAsString(), testUri.toString());
@@ -1952,9 +1689,9 @@
 
   testUsingContext('FlutterDevice uses dartdevc configuration when targeting web', () async {
     fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-    final FakeDevice mockDevice = FakeDevice(targetPlatform: TargetPlatform.web_javascript);
+    final FakeDevice device = FakeDevice(targetPlatform: TargetPlatform.web_javascript);
     final DefaultResidentCompiler residentCompiler = (await FlutterDevice.create(
-      mockDevice,
+      device,
       buildInfo: const BuildInfo(
         BuildMode.debug,
         '',
@@ -1982,10 +1719,10 @@
 
   testUsingContext('FlutterDevice uses dartdevc configuration when targeting web with null-safety autodetected', () async {
     fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-    final FakeDevice mockDevice = FakeDevice(targetPlatform: TargetPlatform.web_javascript);
+    final FakeDevice device = FakeDevice(targetPlatform: TargetPlatform.web_javascript);
 
     final DefaultResidentCompiler residentCompiler = (await FlutterDevice.create(
-      mockDevice,
+      device,
       buildInfo: const BuildInfo(
         BuildMode.debug,
         '',
@@ -2013,10 +1750,10 @@
 
   testUsingContext('FlutterDevice passes flutter-widget-cache flag when feature is enabled', () async {
     fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-    final FakeDevice mockDevice = FakeDevice(targetPlatform: TargetPlatform.android_arm);
+    final FakeDevice device = FakeDevice(targetPlatform: TargetPlatform.android_arm);
 
     final DefaultResidentCompiler residentCompiler = (await FlutterDevice.create(
-      mockDevice,
+      device,
       buildInfo: const BuildInfo(
         BuildMode.debug,
         '',
@@ -2037,11 +1774,11 @@
 
    testUsingContext('FlutterDevice passes alternative-invalidation-strategy flag', () async {
     fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-    final FakeDevice mockDevice = FakeDevice(targetPlatform: TargetPlatform.android_arm);
+    final FakeDevice device = FakeDevice(targetPlatform: TargetPlatform.android_arm);
 
 
     final DefaultResidentCompiler residentCompiler = (await FlutterDevice.create(
-      mockDevice,
+      device,
       buildInfo: const BuildInfo(
         BuildMode.debug,
         '',
@@ -2061,10 +1798,10 @@
 
    testUsingContext('FlutterDevice passes initializeFromDill parameter if specified', () async {
     fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-    final FakeDevice mockDevice = FakeDevice(targetPlatform: TargetPlatform.android_arm);
+    final FakeDevice device = FakeDevice(targetPlatform: TargetPlatform.android_arm);
 
     final DefaultResidentCompiler residentCompiler = (await FlutterDevice.create(
-      mockDevice,
+      device,
       buildInfo: const BuildInfo(
         BuildMode.debug,
         '',
@@ -2084,7 +1821,7 @@
 
   testUsingContext('Handle existing VM service clients DDS error', () => testbed.run(() async {
     fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-    final FakeDevice mockDevice = FakeDevice()
+    final FakeDevice device = FakeDevice()
       ..dds = DartDevelopmentService();
     ddsLauncherCallback = (Uri uri, {bool enableAuthCodes, bool ipv6, Uri serviceUri}) {
       throw FakeDartDevelopmentServiceException(message:
@@ -2092,7 +1829,7 @@
       );
     };
     final TestFlutterDevice flutterDevice = TestFlutterDevice(
-      mockDevice,
+      device,
       observatoryUris: Stream<Uri>.value(testUri),
     );
     bool caught = false;
@@ -2126,13 +1863,13 @@
 
   testUsingContext('Failed DDS start outputs error message', () => testbed.run(() async {
     // See https://github.com/flutter/flutter/issues/72385 for context.
-    final FakeDevice mockDevice = FakeDevice()
+    final FakeDevice device = FakeDevice()
       ..dds = DartDevelopmentService();
     ddsLauncherCallback = (Uri uri, {bool enableAuthCodes, bool ipv6, Uri serviceUri}) {
       throw FakeDartDevelopmentServiceException(message: 'No URI');
     };
     final TestFlutterDevice flutterDevice = TestFlutterDevice(
-      mockDevice,
+      device,
       observatoryUris: Stream<Uri>.value(testUri),
     );
     bool caught = false;
@@ -2176,7 +1913,7 @@
   testUsingContext('cleanupAtFinish shuts down resident devtools handler', () => testbed.run(() async {
     residentRunner = HotRunner(
       <FlutterDevice>[
-        mockFlutterDevice,
+        flutterDevice,
       ],
       stayResident: false,
       debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, vmserviceOutFile: 'foo'),
@@ -2189,9 +1926,6 @@
   }));
 }
 
-class MockFlutterDevice extends Mock implements FlutterDevice {}
-class MockResidentCompiler extends Mock implements ResidentCompiler {}
-
 class FakeDartDevelopmentServiceException implements dds.DartDevelopmentServiceException {
   FakeDartDevelopmentServiceException({this.message = defaultMessage});
 
@@ -2226,8 +1960,105 @@
   }
 }
 
-class FakeFlutterDevice extends FlutterDevice {
-  FakeFlutterDevice(
+class FakeFlutterDevice extends Fake implements FlutterDevice {
+  FakeVmServiceHost Function() vmServiceHost;
+  Uri testUri;
+  UpdateFSReport report = UpdateFSReport(
+    success: true,
+    syncedBytes: 0,
+    invalidatedSourcesCount: 1,
+  );
+  Object reportError;
+  Object runColdError;
+  int runHotCode = 0;
+  int runColdCode = 0;
+
+  @override
+  ResidentCompiler generator;
+
+  @override
+  Stream<Uri> get observatoryUris => Stream<Uri>.value(testUri);
+
+  @override
+  FlutterVmService get vmService => vmServiceHost?.call()?.vmService;
+
+  DevFS _devFS;
+
+  @override
+  DevFS get devFS => _devFS;
+
+  @override
+  set devFS(DevFS value) { }
+
+  @override
+  Device device;
+
+  @override
+  Future<void> stopEchoingDeviceLog() async { }
+
+  @override
+  Future<void> initLogReader() async { }
+
+  @override
+  Future<Uri> setupDevFS(String fsName, Directory rootDirectory) async {
+    return testUri;
+  }
+
+  @override
+  Future<int> runHot({HotRunner hotRunner, String route}) async {
+    return runHotCode;
+  }
+
+  @override
+  Future<int> runCold({ColdRunner coldRunner, String route}) async {
+    if (runColdError != null) {
+      throw runColdError;
+    }
+    return runColdCode;
+  }
+
+  @override
+  Future<void> connect({
+    ReloadSources reloadSources,
+    Restart restart,
+    CompileExpression compileExpression,
+    GetSkSLMethod getSkSLMethod,
+    PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
+    int hostVmServicePort,
+    int ddsPort,
+    bool disableServiceAuthCodes = false,
+    bool enableDds = true,
+    @required bool allowExistingDdsInstance,
+    bool ipv6 = false,
+  }) async { }
+
+  @override
+  Future<UpdateFSReport> updateDevFS({
+    Uri mainUri,
+    String target,
+    AssetBundle bundle,
+    DateTime firstBuildTime,
+    bool bundleFirstUpload = false,
+    bool bundleDirty = false,
+    bool fullRestart = false,
+    String projectRootPath,
+    String pathToReload,
+    String dillOutputPath,
+    List<Uri> invalidatedFiles,
+    PackageConfig packageConfig,
+  }) async {
+    if (reportError != null) {
+      throw reportError;
+    }
+    return report;
+  }
+
+  @override
+  Future<void> updateReloadStatus(bool wasReloadSuccessful) async { }
+}
+
+class FakeDelegateFlutterDevice extends FlutterDevice {
+  FakeDelegateFlutterDevice(
     Device device,
     BuildInfo buildInfo,
     ResidentCompiler residentCompiler,
@@ -2260,6 +2091,9 @@
 }
 
 class FakeResidentCompiler extends Fake implements ResidentCompiler {
+  CompilerOutput nextOutput;
+  bool didSuppressErrors = false;
+
   @override
   Future<CompilerOutput> recompile(
     Uri mainUri,
@@ -2270,7 +2104,8 @@
     @required FileSystem fs,
     bool suppressErrors = false,
   }) async {
-    return const CompilerOutput('foo.dill', 0, <Uri>[]);
+    didSuppressErrors = suppressErrors;
+    return nextOutput ?? const CompilerOutput('foo.dill', 0, <Uri>[]);
   }
 
   @override