tokio-test provides testing utilities for Tokio and futures-based code. It includes mock I/O types, task harnesses for polling futures, and stream testing utilities.
Installation
Addtokio-test to your dev dependencies:
Cargo.toml
tokio-test is typically used only in dev-dependencies since it’s designed for testing.Core Features
Mock I/O
Scriptable AsyncRead/AsyncWrite implementations
Task Harness
Poll futures without runtime boilerplate
Stream Testing
Mock streams for testing stream consumers
Mock I/O
Theio module provides mock types that follow a predefined script of read and write operations. This is perfect for testing networking code without real network I/O.
Basic Mock Builder
Simulating Read Errors
Simulating Write Errors
Adding Delays
Simulate network latency:Testing Protocol Implementation
Task Harness
Thetask module provides utilities for polling futures without needing the full runtime setup.
Basic Task Spawning
Testing Pending Futures
Tracking Wakeups
The task harness tracks how many times the future has been woken:Testing Streams
The task harness also works with streams:Testing Within Tokio Context
Some futures require the Tokio runtime context. You can still use the task harness inside#[tokio::test]:
Stream Mock
Thestream_mock module provides a way to test stream consumers by controlling what values are yielded.
Basic Stream Mock
block_on Helper
For simple cases,tokio_test::block_on provides a quick way to run async code:
This creates a new current-thread runtime for each call. For more control, use
#[tokio::test] instead.Testing Patterns
Testing Error Handling
Testing Request-Response Patterns
Testing Timeout Behavior
Assertions and Macros
Custom Assertion Helpers
Best Practices
Use Mock I/O for Deterministic Tests
Use Mock I/O for Deterministic Tests
Mock I/O eliminates network unpredictability and makes tests faster and more reliable.
Test Both Success and Error Paths
Test Both Success and Error Paths
Use
read_error and write_error to verify your code handles failures gracefully.Keep Scripts Simple
Keep Scripts Simple
Complex I/O scripts are hard to maintain. Consider breaking tests into smaller units.
Track Wakeups for Efficiency
Track Wakeups for Efficiency
Use
is_woken() to ensure futures don’t wake unnecessarily, which can indicate performance issues.Comparison with Alternatives
Use Case
- Task harness can be used with or without the runtime, but some futures require runtime context.
Resources
API Documentation
Complete API reference on docs.rs
Testing Guide
Comprehensive testing guide on Tokio website
GitHub Repository
View source code and examples
tokio::test macro
Learn about the #[tokio::test] macro