#mocking #smol #async #run-time #compatibility #timer #future

async-time-mock-smol

用于异步运行时(smol 兼容性)的可模拟时间

3 个版本 (重大更新)

0.2.0 2024年1月22日
0.1.0 2023年2月19日
0.0.1 2023年1月11日

#413异步

MIT 许可证

14KB
229

async-time-mock-smol

基于 async-time-mock-core 的 smol 运行时异步时间模拟,受 Mocking Time In Async Rust 中的方法启发。

注意:此库仍处于初级阶段,API 可能会发生变化(即:改进)。请在 GitHub 上留下您的反馈和建议。

另外注意:此版本实现的 API 更类似于 tokio 运行时的 API,而不是 smol 的 Timer API。这可能在将来改变。

Cargo 功能

  • mock:启用模拟时钟。如果您只在测试中启用此功能,则此库将变为 async-std 时间函数的薄包装。
  • stream:为 futures_core::stream::Stream 实现 Interval

示例

use async_time_mock_smol::MockableClock;
use std::{
	sync::atomic::{AtomicBool, Ordering},
	time::Duration,
};

static HAS_SLEPT: AtomicBool = AtomicBool::new(false);

async fn sleep(clock: MockableClock) {
	// Sleep is either mocked or a real smol::Timer::set_after, depending on which variant of `MockableClock` you pass in.
	let _guard = clock.sleep(Duration::from_secs(3600)).await;
	// Dropping this guard signifies that all the effects of the timer have finished.
	// This allows test code to wait until the condition to assert for has happened.

	println!("Slept for an hour");
	HAS_SLEPT.store(true, Ordering::SeqCst);
}

fn main() {
	smol::block_on(
		async {
			let (clock, controller) = MockableClock::mock(); // In production, you can use MockableClock::Real instead

			smol::spawn(sleep(clock)).detach();

			controller.advance_time(Duration::from_secs(600)).await;
			assert!(!HAS_SLEPT.load(Ordering::SeqCst), "Timer won't trigger after just 10 minutes.");

			// advance_time will first trigger the sleep in the task above and then wait until the `_guard` was dropped.
			// This ensures that the task had enough time to actually set `HAS_SLEPT` to `true`.
			controller.advance_time(Duration::from_secs(3000)).await;
			assert!(HAS_SLEPT.load(Ordering::SeqCst), "Timer has triggered after 1 hour.")
		}
	);
}

依赖项

~3–11MB
~130K SLoC