[flutter_tools] remove mocks, globals from golden comparator and test runner tests (#81423)
diff --git a/packages/flutter_tools/lib/src/test/flutter_web_goldens.dart b/packages/flutter_tools/lib/src/test/flutter_web_goldens.dart
index e7fd741..82d7a0e 100644
--- a/packages/flutter_tools/lib/src/test/flutter_web_goldens.dart
+++ b/packages/flutter_tools/lib/src/test/flutter_web_goldens.dart
@@ -4,33 +4,44 @@
// @dart = 2.8
-
import 'dart:async';
import 'dart:typed_data';
+import 'package:meta/meta.dart';
+import 'package:process/process.dart';
+
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
+import '../base/logger.dart';
import '../convert.dart';
-import '../globals_null_migrated.dart' as globals;
import 'test_compiler.dart';
import 'test_config.dart';
/// Helper class to start golden file comparison in a separate process.
///
-/// Golden file comparator is configured using flutter_test_config.dart and that
+/// The golden file comparator is configured using flutter_test_config.dart and that
/// file can contain arbitrary Dart code that depends on dart:ui. Thus it has to
/// be executed in a `flutter_tester` environment. This helper class generates a
/// Dart file configured with flutter_test_config.dart to perform the comparison
/// of golden files.
class TestGoldenComparator {
/// Creates a [TestGoldenComparator] instance.
- TestGoldenComparator(this.shellPath, this.compilerFactory)
- : tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_web_platform.');
+ TestGoldenComparator(this.shellPath, this.compilerFactory, {
+ @required Logger logger,
+ @required FileSystem fileSystem,
+ @required ProcessManager processManager,
+ }) : tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_web_platform.'),
+ _logger = logger,
+ _fileSystem = fileSystem,
+ _processManager = processManager;
final String shellPath;
final Directory tempDir;
final TestCompiler Function() compilerFactory;
+ final Logger _logger;
+ final FileSystem _fileSystem;
+ final ProcessManager _processManager;
TestCompiler _compiler;
TestGoldenComparatorProcess _previousComparator;
@@ -49,10 +60,10 @@
return _previousComparator;
}
- final String bootstrap = TestGoldenComparatorProcess.generateBootstrap(testUri);
+ final String bootstrap = TestGoldenComparatorProcess.generateBootstrap(_fileSystem.file(testUri), testUri, logger: _logger);
final Process process = await _startProcess(bootstrap);
unawaited(_previousComparator?.close());
- _previousComparator = TestGoldenComparatorProcess(process);
+ _previousComparator = TestGoldenComparatorProcess(process, logger: _logger);
_previousTestUri = testUri;
return _previousComparator;
@@ -70,7 +81,7 @@
shellPath,
'--disable-observatory',
'--non-interactive',
- '--packages=${globals.fs.path.join('.dart_tool', 'package_config.json')}',
+ '--packages=${_fileSystem.path.join('.dart_tool', 'package_config.json')}',
output,
];
@@ -78,7 +89,7 @@
// Chrome is the only supported browser currently.
'FLUTTER_TEST_BROWSER': 'chrome',
};
- return globals.processManager.start(command, environment: environment);
+ return _processManager.start(command, environment: environment);
}
Future<String> compareGoldens(Uri testUri, Uint8List bytes, Uri goldenKey, bool updateGoldens) async {
@@ -100,7 +111,7 @@
/// handles communication with the child process.
class TestGoldenComparatorProcess {
/// Creates a [TestGoldenComparatorProcess] backed by [process].
- TestGoldenComparatorProcess(this.process) {
+ TestGoldenComparatorProcess(this.process, {@required Logger logger}) : _logger = logger {
// Pipe stdout and stderr to printTrace and printError.
// Also parse stdout as a stream of JSON objects.
streamIterator = StreamIterator<Map<String, dynamic>>(
@@ -108,7 +119,7 @@
.transform<String>(utf8.decoder)
.transform<String>(const LineSplitter())
.where((String line) {
- globals.printTrace('<<< $line');
+ logger.printTrace('<<< $line');
return line.isNotEmpty && line[0] == '{';
})
.map<dynamic>(jsonDecode)
@@ -118,16 +129,17 @@
.transform<String>(utf8.decoder)
.transform<String>(const LineSplitter())
.forEach((String line) {
- globals.printError('<<< $line');
+ logger.printError('<<< $line');
});
}
+ final Logger _logger;
final Process process;
StreamIterator<Map<String, dynamic>> streamIterator;
Future<void> close() async {
- await process.stdin.close();
process.kill();
+ await process.exitCode;
}
void sendCommand(File imageFile, Uri goldenKey, bool updateGoldens) {
@@ -136,7 +148,7 @@
'key': goldenKey.toString(),
'update': updateGoldens,
});
- globals.printTrace('Preparing to send command: $command');
+ _logger.printTrace('Preparing to send command: $command');
process.stdin.writeln(command);
}
@@ -146,8 +158,8 @@
return streamIterator.current;
}
- static String generateBootstrap(Uri testUri) {
- final File testConfigFile = findTestConfigFile(globals.fs.file(testUri), globals.logger);
+ static String generateBootstrap(File testFile, Uri testUri, {@required Logger logger}) {
+ final File testConfigFile = findTestConfigFile(testFile, logger);
// Generate comparator process for the file.
return '''
import 'dart:convert'; // flutter_ignore: dart_convert_import
diff --git a/packages/flutter_tools/lib/src/test/flutter_web_platform.dart b/packages/flutter_tools/lib/src/test/flutter_web_platform.dart
index 3b9ad88..03a0762 100644
--- a/packages/flutter_tools/lib/src/test/flutter_web_platform.dart
+++ b/packages/flutter_tools/lib/src/test/flutter_web_platform.dart
@@ -12,6 +12,7 @@
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
import 'package:pool/pool.dart';
+import 'package:process/process.dart';
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_static/shelf_static.dart';
@@ -51,6 +52,7 @@
@required ChromiumLauncher chromiumLauncher,
@required Logger logger,
@required Artifacts artifacts,
+ @required ProcessManager processManager,
}) : _fileSystem = fileSystem,
_flutterToolPackageConfig = flutterToolPackageConfig,
_chromiumLauncher = chromiumLauncher,
@@ -75,6 +77,9 @@
_testGoldenComparator = TestGoldenComparator(
shellPath,
() => TestCompiler(buildInfo, flutterProject),
+ fileSystem: _fileSystem,
+ logger: _logger,
+ processManager: processManager,
);
}
@@ -111,6 +116,7 @@
@required Logger logger,
@required ChromiumLauncher chromiumLauncher,
@required Artifacts artifacts,
+ @required ProcessManager processManager,
}) async {
final shelf_io.IOServer server = shelf_io.IOServer(await HttpMultiServer.loopback(0));
final PackageConfig packageConfig = await loadPackageConfigWithLogging(
@@ -138,6 +144,7 @@
artifacts: artifacts,
logger: logger,
nullAssertions: nullAssertions,
+ processManager: processManager,
);
}
diff --git a/packages/flutter_tools/lib/src/test/runner.dart b/packages/flutter_tools/lib/src/test/runner.dart
index 25c0eff..df23b33 100644
--- a/packages/flutter_tools/lib/src/test/runner.dart
+++ b/packages/flutter_tools/lib/src/test/runner.dart
@@ -168,6 +168,7 @@
logger: globals.logger,
fileSystem: globals.fs,
artifacts: globals.artifacts,
+ processManager: globals.processManager,
chromiumLauncher: ChromiumLauncher(
fileSystem: globals.fs,
platform: globals.platform,
diff --git a/packages/flutter_tools/test/general.shard/flutter_tester_device_test.dart b/packages/flutter_tools/test/general.shard/flutter_tester_device_test.dart
index e5226fb..2bf8d87 100644
--- a/packages/flutter_tools/test/general.shard/flutter_tester_device_test.dart
+++ b/packages/flutter_tools/test/general.shard/flutter_tester_device_test.dart
@@ -17,8 +17,8 @@
import 'package:flutter_tools/src/test/flutter_tester_device.dart';
import 'package:flutter_tools/src/test/font_config_manager.dart';
import 'package:meta/meta.dart';
-import 'package:mockito/mockito.dart';
import 'package:stream_channel/stream_channel.dart';
+import 'package:test/fake.dart';
import '../src/common.dart';
import '../src/context.dart';
@@ -80,7 +80,7 @@
], environment: <String, String>{
'FLUTTER_TEST': expectedFlutterTestValue,
'FONTCONFIG_FILE': device.fontConfigManager.fontConfigFile.path,
- 'SERVER_PORT': 'null',
+ 'SERVER_PORT': '0',
'APP_NAME': '',
});
}
@@ -244,17 +244,28 @@
@override
Future<DartDevelopmentService> startDds(Uri uri) async {
_ddsServiceUriCompleter.complete(uri);
- final MockDartDevelopmentService mock = MockDartDevelopmentService();
- when(mock.uri).thenReturn(Uri.parse('http://localhost:${debuggingOptions.hostVmServicePort}'));
- return mock;
+ return FakeDartDevelopmentService(Uri.parse('http://localhost:${debuggingOptions.hostVmServicePort}'), Uri.parse('http://localhost:8080'));
}
@override
- Future<HttpServer> bind(InternetAddress host, int port) async => MockHttpServer();
+ Future<HttpServer> bind(InternetAddress host, int port) async => FakeHttpServer();
@override
Future<StreamChannel<String>> get remoteChannel async => StreamChannelController<String>().foreign;
}
-class MockDartDevelopmentService extends Mock implements DartDevelopmentService {}
-class MockHttpServer extends Mock implements HttpServer {}
+class FakeDartDevelopmentService extends Fake implements DartDevelopmentService {
+ FakeDartDevelopmentService(this.uri, this.original);
+
+ final Uri original;
+
+ @override
+ final Uri uri;
+
+ @override
+ Uri get remoteVmServiceUri => original;
+}
+class FakeHttpServer extends Fake implements HttpServer {
+ @override
+ int get port => 0;
+}
diff --git a/packages/flutter_tools/test/general.shard/web/golden_comparator_process_test.dart b/packages/flutter_tools/test/general.shard/web/golden_comparator_process_test.dart
index efc85cd..e11e46e 100644
--- a/packages/flutter_tools/test/general.shard/web/golden_comparator_process_test.dart
+++ b/packages/flutter_tools/test/general.shard/web/golden_comparator_process_test.dart
@@ -7,16 +7,14 @@
import 'dart:convert';
import 'package:flutter_tools/src/base/file_system.dart';
+import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
import 'package:flutter_tools/src/test/flutter_web_goldens.dart';
import '../../src/common.dart';
import '../../src/fakes.dart';
-import '../../src/testbed.dart';
void main() {
- final Testbed testbed = Testbed();
-
group('Test that TestGoldenComparatorProcess', () {
File imageFile;
Uri goldenKey;
@@ -35,7 +33,7 @@
);
});
- test('can pass data', () => testbed.run(() async {
+ testWithoutContext('can pass data', () async {
final Map<String, dynamic> expectedResponse = <String, dynamic>{
'success': true,
'message': 'some message',
@@ -44,7 +42,7 @@
final FakeProcess mockProcess = createFakeProcess(jsonEncode(expectedResponse) + '\n');
final MemoryIOSink ioSink = mockProcess.stdin as MemoryIOSink;
- final TestGoldenComparatorProcess process = TestGoldenComparatorProcess(mockProcess);
+ final TestGoldenComparatorProcess process = TestGoldenComparatorProcess(mockProcess, logger: BufferLogger.test());
process.sendCommand(imageFile, goldenKey, false);
final Map<String, dynamic> response = await process.getResponse();
@@ -52,9 +50,9 @@
expect(response, expectedResponse);
expect(stringToStdin, '{"imageFile":"test_image_file","key":"file://golden_key/","update":false}\n');
- }));
+ });
- test('can handle multiple requests', () => testbed.run(() async {
+ testWithoutContext('can handle multiple requests', () async {
final Map<String, dynamic> expectedResponse1 = <String, dynamic>{
'success': true,
'message': 'some message',
@@ -67,7 +65,7 @@
final FakeProcess mockProcess = createFakeProcess(jsonEncode(expectedResponse1) + '\n' + jsonEncode(expectedResponse2) + '\n');
final MemoryIOSink ioSink = mockProcess.stdin as MemoryIOSink;
- final TestGoldenComparatorProcess process = TestGoldenComparatorProcess(mockProcess);
+ final TestGoldenComparatorProcess process = TestGoldenComparatorProcess(mockProcess, logger: BufferLogger.test());
process.sendCommand(imageFile, goldenKey, false);
final Map<String, dynamic> response1 = await process.getResponse();
@@ -80,9 +78,9 @@
expect(response1, expectedResponse1);
expect(response2, expectedResponse2);
expect(stringToStdin, '{"imageFile":"test_image_file","key":"file://golden_key/","update":false}\n{"imageFile":"second_test_image_file","key":"file://second_golden_key/","update":true}\n');
- }));
+ });
- test('ignores anything that does not look like JSON', () => testbed.run(() async {
+ testWithoutContext('ignores anything that does not look like JSON', () async {
final Map<String, dynamic> expectedResponse = <String, dynamic>{
'success': true,
'message': 'some message',
@@ -97,7 +95,7 @@
''');
final MemoryIOSink ioSink = mockProcess.stdin as MemoryIOSink;
- final TestGoldenComparatorProcess process = TestGoldenComparatorProcess(mockProcess);
+ final TestGoldenComparatorProcess process = TestGoldenComparatorProcess(mockProcess,logger: BufferLogger.test());
process.sendCommand(imageFile, goldenKey, false);
final Map<String, dynamic> response = await process.getResponse();
@@ -105,7 +103,7 @@
expect(response, expectedResponse);
expect(stringToStdin, '{"imageFile":"test_image_file","key":"file://golden_key/","update":false}\n');
- }));
+ });
});
}
diff --git a/packages/flutter_tools/test/general.shard/web/golden_comparator_test.dart b/packages/flutter_tools/test/general.shard/web/golden_comparator_test.dart
index f740d49..78b8de0 100644
--- a/packages/flutter_tools/test/general.shard/web/golden_comparator_test.dart
+++ b/packages/flutter_tools/test/general.shard/web/golden_comparator_test.dart
@@ -4,95 +4,91 @@
// @dart = 2.8
+import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
-import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
+import 'package:file/memory.dart';
+import 'package:flutter_tools/src/base/file_system.dart';
+import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/test/flutter_web_goldens.dart';
import 'package:flutter_tools/src/test/test_compiler.dart';
-import 'package:mockito/mockito.dart';
-import 'package:process/process.dart';
+import 'package:test/fake.dart';
import '../../src/common.dart';
-import '../../src/fakes.dart';
-import '../../src/testbed.dart';
+import '../../src/context.dart';
+
+final Uri goldenKey = Uri.parse('file://golden_key');
+final Uri goldenKey2 = Uri.parse('file://second_golden_key');
+final Uri testUri = Uri.parse('file://test_uri');
+final Uri testUri2 = Uri.parse('file://second_test_uri');
+final Uint8List imageBytes = Uint8List.fromList(<int>[1, 2, 3, 4, 5]);
void main() {
group('Test that TestGoldenComparator', () {
- Testbed testbed;
- Uri goldenKey;
- Uri goldenKey2;
- Uri testUri;
- Uri testUri2;
- Uint8List imageBytes;
- MockProcessManager mockProcessManager;
- MockTestCompiler mockCompiler;
+ FakeProcessManager processManager;
setUp(() {
- goldenKey = Uri.parse('file://golden_key');
- goldenKey2 = Uri.parse('file://second_golden_key');
- testUri = Uri.parse('file://test_uri');
- testUri2 = Uri.parse('file://second_test_uri');
- imageBytes = Uint8List.fromList(<int>[1,2,3,4,5]);
- mockProcessManager = MockProcessManager();
- mockCompiler = MockTestCompiler();
- when(mockCompiler.compile(any)).thenAnswer((_) => Future<String>.value('compiler_output'));
-
- testbed = Testbed(overrides: <Type, Generator>{
- ProcessManager: () {
- return mockProcessManager;
- }
- });
+ processManager = FakeProcessManager.empty();
});
- test('succeed when golden comparison succeed', () => testbed.run(() async {
+ testWithoutContext('succeed when golden comparison succeed', () async {
final Map<String, dynamic> expectedResponse = <String, dynamic>{
'success': true,
'message': 'some message',
};
-
- when(mockProcessManager.start(any, environment: anyNamed('environment')))
- .thenAnswer((Invocation invocation) async {
- return FakeProcess(
- exitCode: Future<int>.value(0),
- stdout: stdoutFromString(jsonEncode(expectedResponse) + '\n'),
- );
- });
+ processManager.addCommand(FakeCommand(
+ command: const <String>[
+ 'shell',
+ '--disable-observatory',
+ '--non-interactive',
+ '--packages=.dart_tool/package_config.json',
+ 'compiler_output'
+ ], stdout: jsonEncode(expectedResponse) + '\n',
+ ));
final TestGoldenComparator comparator = TestGoldenComparator(
'shell',
- () => mockCompiler,
+ () => FakeTestCompiler(),
+ processManager: processManager,
+ fileSystem: MemoryFileSystem.test(),
+ logger: BufferLogger.test(),
);
final String result = await comparator.compareGoldens(testUri, imageBytes, goldenKey, false);
expect(result, null);
- }));
+ });
- test('fail with error message when golden comparison failed', () => testbed.run(() async {
+ testWithoutContext('fail with error message when golden comparison failed', () async {
final Map<String, dynamic> expectedResponse = <String, dynamic>{
'success': false,
'message': 'some message',
};
- when(mockProcessManager.start(any, environment: anyNamed('environment')))
- .thenAnswer((Invocation invocation) async {
- return FakeProcess(
- exitCode: Future<int>.value(0),
- stdout: stdoutFromString(jsonEncode(expectedResponse) + '\n'),
- );
- });
+ processManager.addCommand(FakeCommand(
+ command: const <String>[
+ 'shell',
+ '--disable-observatory',
+ '--non-interactive',
+ '--packages=.dart_tool/package_config.json',
+ 'compiler_output'
+ ], stdout: jsonEncode(expectedResponse) + '\n',
+ ));
final TestGoldenComparator comparator = TestGoldenComparator(
'shell',
- () => mockCompiler,
+ () => FakeTestCompiler(),
+ processManager: processManager,
+ fileSystem: MemoryFileSystem.test(),
+ logger: BufferLogger.test(),
);
final String result = await comparator.compareGoldens(testUri, imageBytes, goldenKey, false);
expect(result, 'some message');
- }));
+ });
- test('reuse the process for the same test file', () => testbed.run(() async {
+ testWithoutContext('reuse the process for the same test file', () async {
final Map<String, dynamic> expectedResponse1 = <String, dynamic>{
'success': false,
'message': 'some message',
@@ -102,27 +98,32 @@
'message': 'some other message',
};
- when(mockProcessManager.start(any, environment: anyNamed('environment')))
- .thenAnswer((Invocation invocation) async {
- return FakeProcess(
- exitCode: Future<int>.value(0),
- stdout: stdoutFromString(jsonEncode(expectedResponse1) + '\n' + jsonEncode(expectedResponse2) + '\n'),
- );
- });
+ processManager.addCommand(FakeCommand(
+ command: const <String>[
+ 'shell',
+ '--disable-observatory',
+ '--non-interactive',
+ '--packages=.dart_tool/package_config.json',
+ 'compiler_output'
+ ], stdout: jsonEncode(expectedResponse1) + '\n' + jsonEncode(expectedResponse2) + '\n',
+ ));
final TestGoldenComparator comparator = TestGoldenComparator(
'shell',
- () => mockCompiler,
+ () => FakeTestCompiler(),
+ processManager: processManager,
+ fileSystem: MemoryFileSystem.test(),
+ logger: BufferLogger.test(),
);
final String result1 = await comparator.compareGoldens(testUri, imageBytes, goldenKey, false);
expect(result1, 'some message');
+
final String result2 = await comparator.compareGoldens(testUri, imageBytes, goldenKey2, false);
expect(result2, 'some other message');
- verify(mockProcessManager.start(any, environment: anyNamed('environment'))).called(1);
- }));
+ });
- test('does not reuse the process for different test file', () => testbed.run(() async {
+ testWithoutContext('does not reuse the process for different test file', () async {
final Map<String, dynamic> expectedResponse1 = <String, dynamic>{
'success': false,
'message': 'some message',
@@ -132,57 +133,82 @@
'message': 'some other message',
};
- when(mockProcessManager.start(any, environment: anyNamed('environment')))
- .thenAnswer((Invocation invocation) async {
- return FakeProcess(
- exitCode: Future<int>.value(0),
- stdout: stdoutFromString(jsonEncode(expectedResponse1) + '\n' + jsonEncode(expectedResponse2) + '\n'),
- );
- });
+ processManager.addCommand(FakeCommand(
+ command: const <String>[
+ 'shell',
+ '--disable-observatory',
+ '--non-interactive',
+ '--packages=.dart_tool/package_config.json',
+ 'compiler_output'
+ ], stdout: jsonEncode(expectedResponse1) + '\n',
+ ));
+ processManager.addCommand(FakeCommand(
+ command: const <String>[
+ 'shell',
+ '--disable-observatory',
+ '--non-interactive',
+ '--packages=.dart_tool/package_config.json',
+ 'compiler_output'
+ ], stdout: jsonEncode(expectedResponse2) + '\n',
+ ));
final TestGoldenComparator comparator = TestGoldenComparator(
'shell',
- () => mockCompiler,
+ () => FakeTestCompiler(),
+ processManager: processManager,
+ fileSystem: MemoryFileSystem.test(),
+ logger: BufferLogger.test(),
);
final String result1 = await comparator.compareGoldens(testUri, imageBytes, goldenKey, false);
expect(result1, 'some message');
- final String result2 = await comparator.compareGoldens(testUri2, imageBytes, goldenKey2, false);
- expect(result2, 'some message');
- verify(mockProcessManager.start(any, environment: anyNamed('environment'))).called(2);
- }));
- test('removes all temporary files when closed', () => testbed.run(() async {
+ final String result2 = await comparator.compareGoldens(testUri2, imageBytes, goldenKey2, false);
+ expect(result2, 'some other message');
+ });
+
+ testWithoutContext('removes all temporary files when closed', () async {
+ final FileSystem fileSystem = MemoryFileSystem.test();
final Map<String, dynamic> expectedResponse = <String, dynamic>{
'success': true,
'message': 'some message',
};
-
- when(mockProcessManager.start(any, environment: anyNamed('environment')))
- .thenAnswer((Invocation invocation) async {
- return FakeProcess(
- exitCode: Future<int>.value(0),
- stdout: stdoutFromString(jsonEncode(expectedResponse) + '\n'),
- );
- });
+ final StreamController<List<int>> controller = StreamController<List<int>>();
+ final IOSink stdin = IOSink(controller.sink);
+ processManager.addCommand(FakeCommand(
+ command: const <String>[
+ 'shell',
+ '--disable-observatory',
+ '--non-interactive',
+ '--packages=.dart_tool/package_config.json',
+ 'compiler_output'
+ ], stdout: jsonEncode(expectedResponse) + '\n',
+ stdin: stdin,
+ ));
final TestGoldenComparator comparator = TestGoldenComparator(
'shell',
- () => mockCompiler,
+ () => FakeTestCompiler(),
+ processManager: processManager,
+ fileSystem: fileSystem,
+ logger: BufferLogger.test(),
);
final String result = await comparator.compareGoldens(testUri, imageBytes, goldenKey, false);
expect(result, null);
await comparator.close();
- expect(globals.fs.systemTempDirectory.listSync(recursive: true), isEmpty);
- }));
+ expect(fileSystem.systemTempDirectory.listSync(recursive: true), isEmpty);
+ });
});
}
-Stream<List<int>> stdoutFromString(String string) => Stream<List<int>>.fromIterable(<List<int>>[
- utf8.encode(string),
-]);
+class FakeTestCompiler extends Fake implements TestCompiler {
+ @override
+ Future<String> compile(Uri mainDart) {
+ return Future<String>.value('compiler_output');
+ }
-class MockProcessManager extends Mock implements ProcessManager {}
-class MockTestCompiler extends Mock implements TestCompiler {}
+ @override
+ Future<void> dispose() async { }
+}