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.