[flutter_tools] no more MockLogger in tests (#51684)


diff --git a/packages/flutter_tools/lib/src/base/command_help.dart b/packages/flutter_tools/lib/src/base/command_help.dart
index 4a1434c..d716eb9 100644
--- a/packages/flutter_tools/lib/src/base/command_help.dart
+++ b/packages/flutter_tools/lib/src/base/command_help.dart
@@ -175,7 +175,7 @@
     this.description, {
     this.inParenthesis = '',
     @required Logger logger,
-    @required AnsiTerminal terminal,
+    @required Terminal terminal,
     @required Platform platform,
     @required OutputPreferences outputPreferences,
   }) : _logger = logger,
@@ -185,7 +185,7 @@
 
   final Logger _logger;
 
-  final AnsiTerminal _terminal;
+  final Terminal _terminal;
 
   final Platform _platform;
 
diff --git a/packages/flutter_tools/lib/src/base/logger.dart b/packages/flutter_tools/lib/src/base/logger.dart
index 0f52351..88256ca 100644
--- a/packages/flutter_tools/lib/src/base/logger.dart
+++ b/packages/flutter_tools/lib/src/base/logger.dart
@@ -7,9 +7,10 @@
 import 'package:meta/meta.dart';
 
 import '../base/context.dart';
+import '../convert.dart';
 import '../globals.dart' as globals;
 import 'io.dart';
-import 'terminal.dart' show AnsiTerminal, TerminalColor, OutputPreferences;
+import 'terminal.dart' show AnsiTerminal, Terminal, TerminalColor, OutputPreferences;
 import 'utils.dart';
 
 const int kDefaultStatusPadding = 59;
@@ -57,7 +58,7 @@
 
   bool get hasTerminal;
 
-  AnsiTerminal get _terminal;
+  Terminal get _terminal;
 
   OutputPreferences get _outputPreferences;
 
@@ -380,11 +381,21 @@
        _timeoutConfiguration = timeoutConfiguration,
        _stopwatchFactory = stopwatchFactory;
 
+  @visibleForTesting
+  BufferLogger.test({
+    Terminal terminal,
+    OutputPreferences outputPreferences,
+  }) : _terminal = terminal ?? Terminal.test(),
+       _outputPreferences = outputPreferences ?? OutputPreferences.test(),
+       _timeoutConfiguration = const TimeoutConfiguration(),
+       _stopwatchFactory = const StopwatchFactory();
+
+
   @override
   final OutputPreferences _outputPreferences;
 
   @override
-  final AnsiTerminal _terminal;
+  final Terminal _terminal;
 
   @override
   final TimeoutConfiguration _timeoutConfiguration;
@@ -400,10 +411,12 @@
   final StringBuffer _error = StringBuffer();
   final StringBuffer _status = StringBuffer();
   final StringBuffer _trace = StringBuffer();
+  final StringBuffer _events = StringBuffer();
 
   String get errorText => _error.toString();
   String get statusText => _status.toString();
   String get traceText => _trace.toString();
+  String get eventText => _events.toString();
 
   @override
   bool get hasTerminal => false;
@@ -481,10 +494,16 @@
     _error.clear();
     _status.clear();
     _trace.clear();
+    _events.clear();
   }
 
   @override
-  void sendEvent(String name, [Map<String, dynamic> args]) { }
+  void sendEvent(String name, [Map<String, dynamic> args]) {
+    _events.write(json.encode(<String, Object>{
+      'name': name,
+      'args': args
+    }));
+  }
 }
 
 class VerboseLogger extends Logger {
@@ -500,7 +519,7 @@
   final Stopwatch _stopwatch;
 
   @override
-  AnsiTerminal get _terminal => parent._terminal;
+  Terminal get _terminal => parent._terminal;
 
   @override
   OutputPreferences get _outputPreferences => parent._outputPreferences;
diff --git a/packages/flutter_tools/lib/src/base/terminal.dart b/packages/flutter_tools/lib/src/base/terminal.dart
index 448da61..e931cf8 100644
--- a/packages/flutter_tools/lib/src/base/terminal.dart
+++ b/packages/flutter_tools/lib/src/base/terminal.dart
@@ -85,7 +85,58 @@
   }
 }
 
-class AnsiTerminal {
+/// The command line terminal, if available.
+abstract class Terminal {
+  factory Terminal.test() = _TestTerminal;
+
+  /// Whether the current terminal supports color escape codes.
+  bool get supportsColor;
+
+  /// Whether the current terminal can display emoji.
+  bool get supportsEmoji;
+
+  /// Whether we are interacting with the flutter tool via the terminal.
+  ///
+  /// If not set, defaults to false.
+  bool get usesTerminalUi;
+  set usesTerminalUi(bool value);
+
+  String bolden(String message);
+
+  String color(String message, TerminalColor color);
+
+  String clearScreen();
+
+  set singleCharMode(bool value);
+
+  /// Return keystrokes from the console.
+  ///
+  /// Useful when the console is in [singleCharMode].
+  Stream<String> get keystrokes;
+
+  /// Prompts the user to input a character within a given list. Re-prompts if
+  /// entered character is not in the list.
+  ///
+  /// The `prompt`, if non-null, is the text displayed prior to waiting for user
+  /// input each time. If `prompt` is non-null and `displayAcceptedCharacters`
+  /// is true, the accepted keys are printed next to the `prompt`.
+  ///
+  /// The returned value is the user's input; if `defaultChoiceIndex` is not
+  /// null, and the user presses enter without any other input, the return value
+  /// will be the character in `acceptedCharacters` at the index given by
+  /// `defaultChoiceIndex`.
+  ///
+  /// If [usesTerminalUi] is false, throws a [StateError].
+  Future<String> promptForCharInput(
+    List<String> acceptedCharacters, {
+    @required Logger logger,
+    String prompt,
+    int defaultChoiceIndex,
+    bool displayAcceptedCharacters = true,
+  });
+}
+
+class AnsiTerminal implements Terminal {
   AnsiTerminal({
     @required io.Stdio stdio,
     @required Platform platform,
@@ -122,12 +173,14 @@
 
   static String colorCode(TerminalColor color) => _colorMap[color];
 
+  @override
   bool get supportsColor => _platform.stdoutSupportsAnsi ?? false;
 
   // Assume unicode emojis are supported when not on Windows.
   // If we are on Windows, unicode emojis are supported in Windows Terminal,
   // which sets the WT_SESSION environment variable. See:
   // https://github.com/microsoft/terminal/blob/master/doc/user-docs/index.md#tips-and-tricks
+  @override
   bool get supportsEmoji => !_platform.isWindows
     || _platform.environment.containsKey('WT_SESSION');
 
@@ -135,11 +188,10 @@
     '(${RegExp.escape(resetBold)}|${RegExp.escape(bold)})',
   );
 
-  /// Whether we are interacting with the flutter tool via the terminal.
-  ///
-  /// If not set, defaults to false.
+  @override
   bool usesTerminalUi = false;
 
+  @override
   String bolden(String message) {
     assert(message != null);
     if (!supportsColor || message.isEmpty) {
@@ -160,6 +212,7 @@
         : result;
   }
 
+  @override
   String color(String message, TerminalColor color) {
     assert(message != null);
     if (!supportsColor || color == null || message.isEmpty) {
@@ -181,8 +234,10 @@
         : result;
   }
 
+  @override
   String clearScreen() => supportsColor ? clear : '\n\n';
 
+  @override
   set singleCharMode(bool value) {
     if (!_stdio.stdinHasTerminal) {
       return;
@@ -200,27 +255,13 @@
 
   Stream<String> _broadcastStdInString;
 
-  /// Return keystrokes from the console.
-  ///
-  /// Useful when the console is in [singleCharMode].
+  @override
   Stream<String> get keystrokes {
     _broadcastStdInString ??= _stdio.stdin.transform<String>(const AsciiDecoder(allowInvalid: true)).asBroadcastStream();
     return _broadcastStdInString;
   }
 
-  /// Prompts the user to input a character within a given list. Re-prompts if
-  /// entered character is not in the list.
-  ///
-  /// The `prompt`, if non-null, is the text displayed prior to waiting for user
-  /// input each time. If `prompt` is non-null and `displayAcceptedCharacters`
-  /// is true, the accepted keys are printed next to the `prompt`.
-  ///
-  /// The returned value is the user's input; if `defaultChoiceIndex` is not
-  /// null, and the user presses enter without any other input, the return value
-  /// will be the character in `acceptedCharacters` at the index given by
-  /// `defaultChoiceIndex`.
-  ///
-  /// If [usesTerminalUi] is false, throws a [StateError].
+  @override
   Future<String> promptForCharInput(
     List<String> acceptedCharacters, {
     @required Logger logger,
@@ -262,3 +303,39 @@
     return choice;
   }
 }
+
+class _TestTerminal implements Terminal {
+  @override
+  bool usesTerminalUi;
+
+  @override
+  String bolden(String message) => message;
+
+  @override
+  String clearScreen() => '\n\n';
+
+  @override
+  String color(String message, TerminalColor color) => message;
+
+  @override
+  Stream<String> get keystrokes => const Stream<String>.empty();
+
+  @override
+  Future<String> promptForCharInput(List<String> acceptedCharacters, {
+    @required Logger logger,
+    String prompt,
+    int defaultChoiceIndex,
+    bool displayAcceptedCharacters = true,
+  }) {
+    throw UnsupportedError('promptForCharInput not supported in the test terminal.');
+  }
+
+  @override
+  set singleCharMode(bool value) { }
+
+  @override
+  bool get supportsColor => false;
+
+  @override
+  bool get supportsEmoji => false;
+}
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/downgrade_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/downgrade_test.dart
index db627c2..71c198e 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/downgrade_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/downgrade_test.dart
@@ -39,7 +39,7 @@
     processManager = FakeProcessManager.any();
     terminal = MockTerminal();
     fileSystem = MemoryFileSystem.test();
-    bufferLogger = BufferLogger(terminal: terminal, outputPreferences: OutputPreferences.test());
+    bufferLogger = BufferLogger.test(terminal: terminal);
   });
 
   testUsingContext('Downgrade exits on unknown channel', () async {
diff --git a/packages/flutter_tools/test/general.shard/artifacts_test.dart b/packages/flutter_tools/test/general.shard/artifacts_test.dart
index d6d67b1..5e4a2da 100644
--- a/packages/flutter_tools/test/general.shard/artifacts_test.dart
+++ b/packages/flutter_tools/test/general.shard/artifacts_test.dart
@@ -32,7 +32,7 @@
         rootOverride: cacheRoot,
         fileSystem: fileSystem,
         platform: platform,
-        logger: MockLogger(),
+        logger: BufferLogger.test(),
         osUtils: MockOperatingSystemUtils(),
       );
       artifacts = CachedArtifacts(
@@ -84,7 +84,7 @@
         rootOverride: cacheRoot,
         fileSystem: fileSystem,
         platform: platform,
-        logger: MockLogger(),
+        logger: BufferLogger.test(),
         osUtils: MockOperatingSystemUtils(),
       );
       artifacts = LocalEngineArtifacts(fileSystem.currentDirectory.path,
@@ -146,5 +146,4 @@
   });
 }
 
-class MockLogger extends Mock implements Logger {}
 class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {}
diff --git a/packages/flutter_tools/test/general.shard/base/command_help_test.dart b/packages/flutter_tools/test/general.shard/base/command_help_test.dart
index b04c9df..400019f 100644
--- a/packages/flutter_tools/test/general.shard/base/command_help_test.dart
+++ b/packages/flutter_tools/test/general.shard/base/command_help_test.dart
@@ -6,27 +6,25 @@
 import 'package:flutter_tools/src/base/logger.dart';
 import 'package:flutter_tools/src/base/terminal.dart' show AnsiTerminal, OutputPreferences;
 import 'package:meta/meta.dart';
-import 'package:mockito/mockito.dart';
 import 'package:platform/platform.dart';
 
 import '../../src/common.dart';
 import '../../src/mocks.dart' show MockStdio;
 
-class MockLogger extends Mock implements Logger {}
-
 CommandHelp _createCommandHelp({
   @required bool ansi,
   @required int wrapColumn,
 }) {
-  final MockPlatform mockPlatform = MockPlatform();
-  when(mockPlatform.stdoutSupportsAnsi).thenReturn(ansi);
+  final Platform platform = FakePlatform(
+    stdoutSupportsAnsi: ansi,
+  );
   return CommandHelp(
-    logger: MockLogger(),
+    logger: BufferLogger.test(),
     terminal: AnsiTerminal(
       stdio:  MockStdio(),
-      platform: mockPlatform,
+      platform: platform,
     ),
-    platform: mockPlatform,
+    platform: platform,
     outputPreferences: OutputPreferences.test(
       showColor: ansi,
       wrapColumn: wrapColumn,
@@ -202,10 +200,3 @@
     });
   });
 }
-
-class MockPlatform extends Mock implements Platform {
-  @override
-  Map<String, String> environment = <String, String>{
-    'FLUTTER_ROOT': '/',
-  };
-}
diff --git a/packages/flutter_tools/test/general.shard/base/logger_test.dart b/packages/flutter_tools/test/general.shard/base/logger_test.dart
index 36de0f4..c8dea3a 100644
--- a/packages/flutter_tools/test/general.shard/base/logger_test.dart
+++ b/packages/flutter_tools/test/general.shard/base/logger_test.dart
@@ -32,11 +32,7 @@
     });
 
     testWithoutContext('error', () async {
-      final BufferLogger mockLogger = BufferLogger(
-        terminal: AnsiTerminal(
-          stdio: mocks.MockStdio(),
-          platform: _kNoAnsiPlatform,
-        ),
+      final BufferLogger mockLogger = BufferLogger.test(
         outputPreferences: OutputPreferences.test(showColor: false),
       );
       final VerboseLogger verboseLogger = VerboseLogger(
diff --git a/packages/flutter_tools/test/general.shard/base/os_test.dart b/packages/flutter_tools/test/general.shard/base/os_test.dart
index 93e2dbf..751e8b7 100644
--- a/packages/flutter_tools/test/general.shard/base/os_test.dart
+++ b/packages/flutter_tools/test/general.shard/base/os_test.dart
@@ -19,8 +19,6 @@
 const String kPath1 = '/bar/bin/$kExecutable';
 const String kPath2 = '/another/bin/$kExecutable';
 
-class MockLogger extends Mock implements Logger {}
-
 void main() {
   MockProcessManager mockProcessManager;
 
@@ -31,7 +29,7 @@
   OperatingSystemUtils createOSUtils(Platform platform) {
     return OperatingSystemUtils(
       fileSystem: MemoryFileSystem(),
-      logger: MockLogger(),
+      logger: BufferLogger.test(),
       platform: platform,
       processManager: mockProcessManager,
     );
diff --git a/packages/flutter_tools/test/general.shard/base/process_test.dart b/packages/flutter_tools/test/general.shard/base/process_test.dart
index 0259767..f8ed20a 100644
--- a/packages/flutter_tools/test/general.shard/base/process_test.dart
+++ b/packages/flutter_tools/test/general.shard/base/process_test.dart
@@ -19,8 +19,6 @@
                                    MockStdio,
                                    flakyProcessFactory;
 
-class MockLogger extends Mock implements Logger {}
-
 void main() {
   group('process exceptions', () {
     ProcessManager mockProcessManager;
@@ -30,7 +28,7 @@
       mockProcessManager = PlainMockProcessManager();
       processUtils = ProcessUtils(
         processManager: mockProcessManager,
-        logger: MockLogger(),
+        logger: BufferLogger.test(),
       );
     });
 
@@ -50,7 +48,7 @@
       int postProcessRecording;
       int cleanup;
 
-      final ShutdownHooks shutdownHooks = ShutdownHooks(logger: MockLogger());
+      final ShutdownHooks shutdownHooks = ShutdownHooks(logger: BufferLogger.test());
 
       shutdownHooks.addShutdownHook(() async {
         serializeRecording1 = i++;
@@ -132,11 +130,11 @@
       mockProcessManager = MockProcessManager();
       processUtils = ProcessUtils(
         processManager: mockProcessManager,
-        logger: MockLogger(),
+        logger: BufferLogger.test(),
       );
       flakyProcessUtils = ProcessUtils(
         processManager: flakyProcessManager,
-        logger: MockLogger(),
+        logger: BufferLogger.test(),
       );
     });
 
@@ -345,7 +343,7 @@
       mockProcessManager = MockProcessManager();
       processUtils = ProcessUtils(
         processManager: mockProcessManager,
-        logger: MockLogger(),
+        logger: BufferLogger.test(),
       );
     });
 
@@ -372,7 +370,7 @@
       mockProcessManager = MockProcessManager();
       processUtils = ProcessUtils(
         processManager: mockProcessManager,
-        logger: MockLogger(),
+        logger: BufferLogger.test(),
       );
     });
 
diff --git a/packages/flutter_tools/test/general.shard/build_system/depfile_test.dart b/packages/flutter_tools/test/general.shard/build_system/depfile_test.dart
index d39013e..cbc8b7f 100644
--- a/packages/flutter_tools/test/general.shard/build_system/depfile_test.dart
+++ b/packages/flutter_tools/test/general.shard/build_system/depfile_test.dart
@@ -6,7 +6,6 @@
 import 'package:flutter_tools/src/base/file_system.dart';
 import 'package:flutter_tools/src/base/logger.dart';
 import 'package:flutter_tools/src/build_system/depfile.dart';
-import 'package:mockito/mockito.dart';
 import 'package:platform/platform.dart';
 
 import '../../src/common.dart';
@@ -18,7 +17,7 @@
   setUp(() {
     fileSystem = MemoryFileSystem.test();
     depfileService = DepfileService(
-      logger: MockLogger(),
+      logger: BufferLogger.test(),
       fileSystem: fileSystem,
       platform: FakePlatform(operatingSystem: 'linux'),
     );
@@ -64,7 +63,7 @@
   testWithoutContext('Can parse depfile with windows file paths', () {
     fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
     depfileService = DepfileService(
-      logger: MockLogger(),
+      logger: BufferLogger.test(),
       fileSystem: fileSystem,
       platform: FakePlatform(operatingSystem: 'windows'),
     );
@@ -80,7 +79,7 @@
   testWithoutContext('Can escape depfile with windows file paths and spaces in directory names', () {
     fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
     depfileService = DepfileService(
-      logger: MockLogger(),
+      logger: BufferLogger.test(),
       fileSystem: fileSystem,
       platform: FakePlatform(operatingSystem: 'windows'),
     );
@@ -176,5 +175,3 @@
     expect(depfile.outputs.single.path, 'foo.dart.js');
   });
 }
-
-class MockLogger extends Mock implements Logger {}
\ No newline at end of file
diff --git a/packages/flutter_tools/test/general.shard/config_test.dart b/packages/flutter_tools/test/general.shard/config_test.dart
index a350f87..a23e6e0 100644
--- a/packages/flutter_tools/test/general.shard/config_test.dart
+++ b/packages/flutter_tools/test/general.shard/config_test.dart
@@ -7,13 +7,10 @@
 import 'package:flutter_tools/src/base/file_system.dart';
 import 'package:flutter_tools/src/base/logger.dart';
 import 'package:flutter_tools/src/base/terminal.dart';
-import 'package:mockito/mockito.dart';
 import 'package:platform/platform.dart';
 
 import '../src/common.dart';
 
-class MockLogger extends Mock implements Logger {}
-
 void main() {
   Config config;
   MemoryFileSystem memoryFileSystem;
@@ -30,7 +27,7 @@
     config = Config(
       'example',
       fileSystem: memoryFileSystem,
-      logger: MockLogger(),
+      logger: BufferLogger.test(),
       platform: fakePlatform,
     );
   });
diff --git a/packages/flutter_tools/test/general.shard/ios/devices_test.dart b/packages/flutter_tools/test/general.shard/ios/devices_test.dart
index 1daacc4..e3dd8c7 100644
--- a/packages/flutter_tools/test/general.shard/ios/devices_test.dart
+++ b/packages/flutter_tools/test/general.shard/ios/devices_test.dart
@@ -38,28 +38,6 @@
 import '../../src/context.dart';
 import '../../src/mocks.dart';
 
-class MockIOSApp extends Mock implements IOSApp {}
-class MockApplicationPackage extends Mock implements ApplicationPackage {}
-class MockArtifacts extends Mock implements Artifacts {}
-class MockCache extends Mock implements Cache {}
-class MockDevicePortForwarder extends Mock implements DevicePortForwarder {}
-class MockDirectory extends Mock implements Directory {}
-class MockFile extends Mock implements File {}
-class MockFileSystem extends Mock implements FileSystem {}
-class MockForwardedPort extends Mock implements ForwardedPort {}
-class MockIMobileDevice extends Mock implements IMobileDevice {}
-class MockIOSDeploy extends Mock implements IOSDeploy {}
-class MockLogger extends Mock implements Logger {}
-class MockMDnsObservatoryDiscovery extends Mock implements MDnsObservatoryDiscovery {}
-class MockMDnsObservatoryDiscoveryResult extends Mock implements MDnsObservatoryDiscoveryResult {}
-class MockPlatform extends Mock implements Platform {}
-class MockPortForwarder extends Mock implements DevicePortForwarder {}
-// src/mocks.dart imports `MockProcessManager` which implements some methods, this is a full mock
-class FullMockProcessManager extends Mock implements ProcessManager {}
-class MockUsage extends Mock implements Usage {}
-class MockXcdevice extends Mock implements XCDevice {}
-class MockXcode extends Mock implements Xcode {}
-
 void main() {
   final FakePlatform macPlatform = FakePlatform.fromPlatform(const LocalPlatform());
   macPlatform.operatingSystem = 'macos';
@@ -72,7 +50,7 @@
     final List<Platform> unsupportedPlatforms = <Platform>[linuxPlatform, windowsPlatform];
     Artifacts mockArtifacts;
     MockCache mockCache;
-    MockLogger mockLogger;
+    Logger logger;
     IOSDeploy iosDeploy;
     FileSystem mockFileSystem;
 
@@ -82,11 +60,11 @@
       const MapEntry<String, String> dyLdLibEntry = MapEntry<String, String>('DYLD_LIBRARY_PATH', '/path/to/libs');
       when(mockCache.dyLdLibEntry).thenReturn(dyLdLibEntry);
       mockFileSystem = MockFileSystem();
-      mockLogger = MockLogger();
+      logger = BufferLogger.test();
       iosDeploy = IOSDeploy(
         artifacts: mockArtifacts,
         cache: mockCache,
-        logger: mockLogger,
+        logger: logger,
         platform: macPlatform,
         processManager: FakeProcessManager.any(),
       );
@@ -189,7 +167,7 @@
         iosDeploy = IOSDeploy(
           artifacts: mockArtifacts,
           cache: mockCache,
-          logger: mockLogger,
+          logger: logger,
           platform: macPlatform,
           processManager: mockProcessManager,
         );
@@ -264,7 +242,7 @@
       ForwardedPort forwardedPort;
       Artifacts mockArtifacts;
       MockCache mockCache;
-      MockLogger mockLogger;
+      Logger logger;
       IOSDeploy iosDeploy;
       FileSystem mockFileSystem;
 
@@ -300,7 +278,7 @@
         iosDeploy = IOSDeploy(
           artifacts: mockArtifacts,
           cache: mockCache,
-          logger: mockLogger,
+          logger: logger,
           platform: macPlatform,
           processManager: FakeProcessManager.any(),
         );
@@ -979,7 +957,7 @@
       MockArtifacts mockArtifacts;
       MockCache mockCache;
       MockFileSystem mockFileSystem;
-      MockLogger mockLogger;
+      Logger logger;
       MockPlatform mockPlatform;
       FullMockProcessManager mockProcessManager;
       const String iosDeployPath = '/path/to/ios-deploy';
@@ -1003,7 +981,7 @@
 
         mockArtifacts = MockArtifacts();
         mockCache = MockCache();
-        mockLogger = MockLogger();
+        logger = BufferLogger.test();
         mockPlatform = MockPlatform();
         when(mockPlatform.environment).thenReturn(<String, String>{});
         when(mockPlatform.isMacOS).thenReturn(true);
@@ -1017,7 +995,7 @@
         iosDeploy = IOSDeploy(
           artifacts: mockArtifacts,
           cache: mockCache,
-          logger: mockLogger,
+          logger: logger,
           platform: mockPlatform,
           processManager: mockProcessManager,
         );
@@ -1102,7 +1080,7 @@
     MockArtifacts mockArtifacts;
     MockCache mockCache;
     MockFileSystem mockFileSystem;
-    MockLogger mockLogger;
+    Logger logger;
     FullMockProcessManager mockProcessManager;
     IOSDeploy iosDeploy;
 
@@ -1110,13 +1088,13 @@
       mockXcdevice = MockXcdevice();
       mockArtifacts = MockArtifacts();
       mockCache = MockCache();
-      mockLogger = MockLogger();
+      logger = BufferLogger.test();
       mockFileSystem = MockFileSystem();
       mockProcessManager = FullMockProcessManager();
       iosDeploy = IOSDeploy(
         artifacts: mockArtifacts,
         cache: mockCache,
-        logger: mockLogger,
+        logger: logger,
         platform: macPlatform,
         processManager: mockProcessManager,
       );
@@ -1201,7 +1179,7 @@
     MockArtifacts mockArtifacts;
     MockCache mockCache;
     MockFileSystem mockFileSystem;
-    MockLogger mockLogger;
+    Logger logger;
     FullMockProcessManager mockProcessManager;
     IOSDeploy iosDeploy;
 
@@ -1210,13 +1188,13 @@
       mockIosProject = MockIosProject();
       mockArtifacts = MockArtifacts();
       mockCache = MockCache();
-      mockLogger = MockLogger();
+      logger = BufferLogger.test();
       mockFileSystem = MockFileSystem();
       mockProcessManager = FullMockProcessManager();
       iosDeploy = IOSDeploy(
         artifacts: mockArtifacts,
         cache: mockCache,
-        logger: mockLogger,
+        logger: logger,
         platform: macPlatform,
         processManager: mockProcessManager,
       );
@@ -1302,7 +1280,7 @@
   group('isSupportedForProject', () {
     Artifacts mockArtifacts;
     MockCache mockCache;
-    MockLogger mockLogger;
+    Logger logger;
     IOSDeploy iosDeploy;
 
     setUp(() {
@@ -1311,7 +1289,7 @@
       iosDeploy = IOSDeploy(
         artifacts: mockArtifacts,
         cache: mockCache,
-        logger: mockLogger,
+        logger: logger,
         platform: macPlatform,
         processManager: FakeProcessManager.any(),
       );
@@ -1424,3 +1402,24 @@
     return _workflows;
   }
 }
+
+class MockIOSApp extends Mock implements IOSApp {}
+class MockApplicationPackage extends Mock implements ApplicationPackage {}
+class MockArtifacts extends Mock implements Artifacts {}
+class MockCache extends Mock implements Cache {}
+class MockDevicePortForwarder extends Mock implements DevicePortForwarder {}
+class MockDirectory extends Mock implements Directory {}
+class MockFile extends Mock implements File {}
+class MockFileSystem extends Mock implements FileSystem {}
+class MockForwardedPort extends Mock implements ForwardedPort {}
+class MockIMobileDevice extends Mock implements IMobileDevice {}
+class MockIOSDeploy extends Mock implements IOSDeploy {}
+class MockMDnsObservatoryDiscovery extends Mock implements MDnsObservatoryDiscovery {}
+class MockMDnsObservatoryDiscoveryResult extends Mock implements MDnsObservatoryDiscoveryResult {}
+class MockPlatform extends Mock implements Platform {}
+class MockPortForwarder extends Mock implements DevicePortForwarder {}
+// src/mocks.dart imports `MockProcessManager` which implements some methods, this is a full mock
+class FullMockProcessManager extends Mock implements ProcessManager {}
+class MockUsage extends Mock implements Usage {}
+class MockXcdevice extends Mock implements XCDevice {}
+class MockXcode extends Mock implements Xcode {}
diff --git a/packages/flutter_tools/test/general.shard/ios/ios_deploy_test.dart b/packages/flutter_tools/test/general.shard/ios/ios_deploy_test.dart
index 391f405..57cc81e 100644
--- a/packages/flutter_tools/test/general.shard/ios/ios_deploy_test.dart
+++ b/packages/flutter_tools/test/general.shard/ios/ios_deploy_test.dart
@@ -18,7 +18,6 @@
 
 class MockArtifacts extends Mock implements Artifacts {}
 class MockCache extends Mock implements Cache {}
-class MockLogger extends Mock implements Logger {}
 class MockPlatform extends Mock implements Platform {}
 class MockProcess extends Mock implements Process {}
 class MockProcessManager extends Mock implements ProcessManager {}
@@ -28,7 +27,7 @@
     Artifacts mockArtifacts;
     Cache mockCache;
     IOSDeploy iosDeploy;
-    Logger mockLogger;
+    Logger logger;
     Platform mockPlatform;
     ProcessManager mockProcessManager;
     const String iosDeployPath = '/path/to/ios-deploy';
@@ -42,7 +41,7 @@
       mockCache = MockCache();
       const MapEntry<String, String> mapEntry = MapEntry<String, String>('DYLD_LIBRARY_PATH', '/path/to/libs');
       when(mockCache.dyLdLibEntry).thenReturn(mapEntry);
-      mockLogger = MockLogger();
+      logger = BufferLogger.test();
       mockPlatform = MockPlatform();
       when(mockPlatform.environment).thenReturn(<String, String>{
         'PATH': '/usr/local/bin:/usr/bin',
@@ -51,7 +50,7 @@
       iosDeploy = IOSDeploy(
         artifacts: mockArtifacts,
         cache: mockCache,
-        logger: mockLogger,
+        logger: logger,
         platform: mockPlatform,
         processManager: mockProcessManager,
       );
diff --git a/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart b/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart
index 18f3be4..c177092 100644
--- a/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart
+++ b/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart
@@ -39,8 +39,7 @@
     fileSystem = MemoryFileSystem();
     fileSystem.file(xcodebuild).createSync(recursive: true);
     terminal = MockAnsiTerminal();
-    logger = BufferLogger(
-      outputPreferences: OutputPreferences.test(),
+    logger = BufferLogger.test(
       terminal: terminal
     );
     xcodeProjectInterpreter = XcodeProjectInterpreter(
@@ -755,7 +754,6 @@
 class MockLocalEngineArtifacts extends Mock implements LocalEngineArtifacts {}
 class MockProcessManager extends Mock implements ProcessManager {}
 class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
-class MockLogger extends Mock implements Logger {}
 class MockAnsiTerminal extends Mock implements AnsiTerminal {
   @override
   bool get supportsColor => false;
diff --git a/packages/flutter_tools/test/general.shard/macos/xcode_test.dart b/packages/flutter_tools/test/general.shard/macos/xcode_test.dart
index 4711149..943212f 100644
--- a/packages/flutter_tools/test/general.shard/macos/xcode_test.dart
+++ b/packages/flutter_tools/test/general.shard/macos/xcode_test.dart
@@ -17,16 +17,12 @@
 import '../../src/common.dart';
 import '../../src/context.dart';
 
-class MockProcessManager extends Mock implements ProcessManager {}
-class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
-class MockPlatform extends Mock implements Platform {}
-
 void main() {
   ProcessManager processManager;
   Logger logger;
 
   setUp(() {
-    logger = MockLogger();
+    logger = BufferLogger.test();
     processManager = MockProcessManager();
   });
 
@@ -570,5 +566,7 @@
   });
 }
 
-class MockLogger extends Mock implements Logger {}
 class MockXcode extends Mock implements Xcode {}
+class MockProcessManager extends Mock implements ProcessManager {}
+class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
+class MockPlatform extends Mock implements Platform {}
diff --git a/packages/flutter_tools/test/general.shard/persistent_tool_state_test.dart b/packages/flutter_tools/test/general.shard/persistent_tool_state_test.dart
index 1f4bfcf..906f533 100644
--- a/packages/flutter_tools/test/general.shard/persistent_tool_state_test.dart
+++ b/packages/flutter_tools/test/general.shard/persistent_tool_state_test.dart
@@ -7,12 +7,9 @@
 import 'package:flutter_tools/src/base/logger.dart';
 import 'package:flutter_tools/src/persistent_tool_state.dart';
 import 'package:flutter_tools/src/version.dart';
-import 'package:mockito/mockito.dart';
 
 import '../src/common.dart';
 
-class MockLogger extends Mock implements Logger {}
-
 void main() {
   testWithoutContext('state can be set and persists', () {
     final MemoryFileSystem fileSystem = MemoryFileSystem();
@@ -21,7 +18,7 @@
     final File stateFile = directory.childFile('.flutter_tool_state');
     final PersistentToolState state1 = PersistentToolState.test(
       directory: directory,
-      logger: MockLogger(),
+      logger: BufferLogger.test(),
     );
     expect(state1.redisplayWelcomeMessage, null);
     state1.redisplayWelcomeMessage = true;
@@ -32,7 +29,7 @@
 
     final PersistentToolState state2 = PersistentToolState.test(
       directory: directory,
-      logger: MockLogger(),
+      logger: BufferLogger.test(),
     );
     expect(state2.redisplayWelcomeMessage, false);
   });
@@ -42,7 +39,7 @@
     final Directory directory = fileSystem.directory('state_dir')..createSync();
     final PersistentToolState state1 = PersistentToolState.test(
       directory: directory,
-      logger: MockLogger(),
+      logger: BufferLogger.test(),
     );
 
     state1.updateLastActiveVersion('abc', Channel.master);
@@ -52,7 +49,7 @@
 
     final PersistentToolState state2 = PersistentToolState.test(
       directory: directory,
-      logger: MockLogger(),
+      logger: BufferLogger.test(),
     );
 
     expect(state2.lastActiveVersion(Channel.master), 'abc');
diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart
index dde12a4..6943e7e 100644
--- a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart
@@ -790,15 +790,17 @@
     await connectionInfoCompleter.future;
 
     // Ensure we got the URL and that it was already launched.
-    verify(globals.logger.sendEvent(
-      'app.webLaunchUrl',
-      argThat(allOf(
-        containsPair('url', 'http://localhost:8765/app/'),
-        containsPair('launched', true),
-      ))
-    ));
+    expect((delegateLogger.delegate as BufferLogger).eventText,
+      contains(json.encode(<String, Object>{
+        'name': 'app.webLaunchUrl',
+        'args': <String, Object>{
+          'url': 'http://localhost:8765/app/',
+          'launched': true,
+        },
+      },
+    )));
   }, overrides: <Type, Generator>{
-    Logger: () => DelegateLogger(MockLogger()),
+    Logger: () => DelegateLogger(BufferLogger.test()),
     ChromeLauncher: () => MockChromeLauncher(),
   }));
 
@@ -829,15 +831,17 @@
     await connectionInfoCompleter.future;
 
     // Ensure we got the URL and that it was not already launched.
-    verify(globals.logger.sendEvent(
-      'app.webLaunchUrl',
-      argThat(allOf(
-        containsPair('url', 'http://localhost:8765/app/'),
-        containsPair('launched', false),
-      ))
-    ));
+    expect((delegateLogger.delegate as BufferLogger).eventText,
+      contains(json.encode(<String, Object>{
+        'name': 'app.webLaunchUrl',
+        'args': <String, Object>{
+          'url': 'http://localhost:8765/app/',
+          'launched': false,
+        },
+      },
+    )));
   }, overrides: <Type, Generator>{
-    Logger: () => DelegateLogger(MockLogger())
+    Logger: () => DelegateLogger(BufferLogger.test())
   }));
 
   test('Successfully turns WebSocketException into ToolExit', () => testbed.run(() async {
@@ -962,6 +966,5 @@
 class MockChromeTab extends Mock implements ChromeTab {}
 class MockWipConnection extends Mock implements WipConnection {}
 class MockWipDebugger extends Mock implements WipDebugger {}
-class MockLogger extends Mock implements Logger {}
 class MockWebServerDevice extends Mock implements WebServerDevice {}
 class MockDevice extends Mock implements Device {}
diff --git a/packages/flutter_tools/test/general.shard/web/chrome_test.dart b/packages/flutter_tools/test/general.shard/web/chrome_test.dart
index 6828298..3312a38 100644
--- a/packages/flutter_tools/test/general.shard/web/chrome_test.dart
+++ b/packages/flutter_tools/test/general.shard/web/chrome_test.dart
@@ -34,10 +34,10 @@
   Platform platform;
   FakeProcessManager processManager;
   OperatingSystemUtils operatingSystemUtils;
-  MockLogger logger;
+  Logger logger;
 
   setUp(() {
-    logger = MockLogger();
+    logger = BufferLogger.test();
     operatingSystemUtils = MockOperatingSystemUtils();
     when(operatingSystemUtils.findFreePort())
         .thenAnswer((Invocation invocation) async {
@@ -163,4 +163,3 @@
 }
 
 class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {}
-class MockLogger extends Mock implements Logger {}