mock_instant
Modules
NOTE As of verison 0.6, the timer resolution is nanosecond-based, which may be much more accurate than the real thing
NOTE As of version 0.5. MockClock/Instant/SystemTime have been moved to specific modules
NOTE The modules, global and thread_local change the behavior across threads. If global is used, the clock keeps its state across threads, otherwise if thread_local is used, a new source is made for each thread. In most cases, especially when unit testing, thread_local will deliver the most expected behavior.
To ensure unsurprising behavior, reset the clock before each test (if that behavior is applicable.)
Basics
This crate allows you to test Instant/Duration/SystemTime code, deterministically.
It provides a replacement std::time::Instant that uses a deterministic 'clock'
You can swap out the std::time::Instant with this one by doing something similar to:
use Instant;
use Instant;
or for a std::time::SystemTime
use ;
use ;
use ;
use Duration;
let now = now;
advance;
advance;
// its been '17' seconds
assert_eq!;
API
// Overrides the current time to this `Duration`
set_time
// Advance the current time by this `Duration`
advance
// Get the current time
time // Overrides the current `SystemTime` to this duration
set_system_time
// Advance the current `SystemTime` by this duration
advance_system_time
// Get the current `SystemTime`
system_time // Determine if this MockClock was thread-local: (useful for assertions to ensure the right mode is being used)
is_thread_local .is_thread_local .is_thread_local
Usage
NOTE The clock starts at Duration::ZERO
In your tests, you can use MockClock::set_time(Duration::ZERO) to reset the clock back to 0. Or, you can set it to some sentinel time value.
Then, before you check your time-based logic, you can advance the clock by some Duration (it'll freeze the time to that duration)
You can also get the current frozen time with MockClock::time
SystemTime is also mockable with a similar API.
Thread-safety
Two modes are provided via modules. The APIs are identical but the MockClock source has different behavior in different threads.
mock_instant::thread_local
MockClockwill have an independent state per threadInstantwill have an independent state per threadSystemTimewill have an independent state per thread
Using thread_local creates a shared clock in each thread of operation within the test application. It is recommended for unit tests and integration tests that test single-threaded behavior.
thread_local will be the module used in most cases and will create the least surprise.
mock_instant::global
MockClockwill have shared state per threadInstantwill have shared state per threadSystemTimewill have shared state per thread
Using global creates a shared clock across all thread of operation within the test application. It is recommended for integration tests that are specifically testing multi-threaded behavior. Using global when not testing multi-threaded behavior is likely to cause inconsistent and confusing errors.
Rust's unit test test-runner executes unit tests in multiple threads (unless directed to run single-threaded). If multiple unit tests are running simultaneouly within the test execution, changes to the global clock (resetting or advancing the clock) in one test can created unexpected results in other tests that are executing simultaneously, by changing the clock when the tests assume the clock is not being changed.
License
License: 0BSD