Dart IOOverrides
last modified April 4, 2025
The IOOverrides
class in Dart provides a way to override standard
IO operations for testing purposes. It's part of Dart's testing utilities.
IOOverrides
allows mocking file system, network, and process
operations. This enables reliable unit tests without real IO operations.
Basic Definition
IOOverrides
is an abstract class in the dart:io
library. It provides hooks to override standard IO operations.
Key features include file system mocking, network call interception, and process execution simulation. It's essential for test isolation.
Basic IOOverrides Usage
This example shows how to override file operations for testing.
import 'dart:io'; class MockFileSystem extends IOOverrides { @override File openFile(String path) { return File('mocked_content.txt'); } } void main() { IOOverrides.runWithOverrides(() { var file = File('test.txt'); print(file.readAsStringSync()); // Reads from mocked_content.txt }, MockFileSystem()); }
We create a custom IOOverrides
implementation that changes file
operations. The runWithOverrides
method executes code with our
overrides active.
$ dart main.dart Content from mocked_content.txt
Mocking Network Calls
This example demonstrates mocking HTTP client requests.
import 'dart:io'; import 'dart:convert'; class MockHttpOverrides extends IOOverrides { @override HttpClient createHttpClient(SecurityContext? context) { return MockHttpClient(); } } class MockHttpClient extends HttpClient { @override Future<HttpClientRequest> getUrl(Uri url) async { return MockHttpClientRequest(); } } class MockHttpClientRequest extends HttpClientRequest { @override Future<HttpClientResponse> close() async { return MockHttpClientResponse(); } } class MockHttpClientResponse extends HttpClientResponse { @override int get statusCode => 200; @override Stream<List<int>> get body => Stream.value(utf8.encode('Mocked response')); } void main() { IOOverrides.runWithOverrides(() async { var client = HttpClient(); var request = await client.getUrl(Uri.parse('https://example.com')); var response = await request.close(); print(await response.transform(utf8.decoder).join()); }, MockHttpOverrides()); }
We override the entire HTTP client stack to return mock responses. This allows testing network-dependent code without real network calls.
$ dart main.dart Mocked response
Overriding Process Execution
This example shows how to mock process execution results.
import 'dart:io'; class MockProcessOverrides extends IOOverrides { @override ProcessResult runProcess(String executable, List<String> arguments, {String? workingDirectory, Map<String, String>? environment}) { return ProcessResult(0, 0, 'Mocked output', ''); } } void main() { IOOverrides.runWithOverrides(() { var result = Process.runSync('ls', ['-la']); print(result.stdout); // Mocked output }, MockProcessOverrides()); }
We override process execution to return predefined results. This is useful for testing code that depends on external commands.
$ dart main.dart Mocked output
Combining Multiple Overrides
This example combines file and network overrides in a single test.
import 'dart:io'; import 'dart:convert'; class CombinedOverrides extends IOOverrides { @override File openFile(String path) => File('mock_file.txt'); @override HttpClient createHttpClient(SecurityContext? context) => MockHttpClient(); } class MockHttpClient extends HttpClient { @override Future<HttpClientRequest> getUrl(Uri url) async => MockHttpClientRequest(); } class MockHttpClientRequest extends HttpClientRequest { @override Future<HttpClientResponse> close() async => MockHttpClientResponse(); } class MockHttpClientResponse extends HttpClientResponse { @override int get statusCode => 200; @override Stream<List<int>> get body => Stream.value(utf8.encode('Mocked HTTP')); } void main() { IOOverrides.runWithOverrides(() async { // Test file operation print(File('test.txt').readAsStringSync()); // Test HTTP operation var client = HttpClient(); var request = await client.getUrl(Uri.parse('https://example.com')); var response = await request.close(); print(await response.transform(utf8.decoder).join()); }, CombinedOverrides()); }
We create a comprehensive override that handles both file and network operations. This enables complex test scenarios with multiple IO dependencies.
$ dart main.dart Content from mock_file.txt Mocked HTTP
Testing with IOOverrides
This example shows a complete unit test using IOOverrides.
import 'dart:io'; import 'package:test/test.dart'; class TestOverrides extends IOOverrides { @override Directory getCurrentDirectory() => Directory('/mock/dir'); } String getCurrentDir() { return Directory.current.path; } void main() { test('Test directory override', () { IOOverrides.runWithOverrides(() { expect(getCurrentDir(), equals('/mock/dir')); }, TestOverrides()); }); }
We test a function that depends on the current directory. The override ensures consistent results regardless of the real environment.
$ dart test main.dart 00:00 +0: Test directory override 00:00 +1: All tests passed!
Best Practices
- Isolation: Keep overrides focused on specific test cases
- Restoration: Overrides automatically revert after runWithOverrides
- Completeness: Implement all required methods when overriding
- Realism: Make mock behavior match real implementations
Source
Dart IOOverrides Documentation
This tutorial covered Dart's IOOverrides class with practical examples showing how to mock various IO operations for reliable testing.
Author
List all Dart tutorials.