我希望能够在我的代码本身中检查它是否正在从测试中运行.这样做是理想的,例如,与测试数据库、Web 服务等交互.一个简单的 bool 就足够了.
I'd like to be able to check within my code itself whether or not it is running from a test. It would be ideal to do this, for example, to interface with test databases, web services, etc. A simple bool would suffice.
Rust 是否有用于此的现有 API?
Does Rust have an existing API for this?
推荐答案测试的运行时检测
运行测试时没有设置全局变量.您可以添加一个,但要正确处理非常复杂.这个例子没有完全正确:
Runtime detection of tests
There's no global variable that is set when running tests. You could add one, but it's pretty complicated to get it right. This example does not get it completely right:
use std::cell::Cell; thread_local! { pub static IS_TESTING: Cell<bool> = Cell::new(false); } fn my_code() -> u8 { if IS_TESTING.with(|t| t.get()) { 0 } else { 42 } } #[test] fn one() { IS_TESTING.with(|t| t.set(true)); assert_eq!(0, my_code()); IS_TESTING.with(|t| t.set(false)); }要正确执行此操作,您需要处理以下事项:
To do this correctly, you need to handle a few things:
测试的编译时间检测
更有可能的是,您想要检测您是否正在编译进行测试.这要简单得多,而且您可能已经在使用相同的技术来有条件地自行编译测试:
Compile time detection of tests
More likely, what you want is to detect if you are compiling for tests. This is much simpler and you are probably already using the same technique to conditionally compile your tests themselves:
fn my_code() -> u8 { if cfg!(test) { 0 } else { 42 } } #[cfg(test)] mod test { use super::*; #[test] fn one() { assert_eq!(0, my_code()); } }依赖注入更好
在编辑上,从代码质量的角度来看,运行时或编译时检测是一个坏主意.与其用大量条件检查乱扔代码,这会使代码复杂化甚至减慢代码速度,不如引入依赖注入:
trait ValueSource { fn value(&self) -> u8; } struct ProductionSource; impl ValueSource for ProductionSource { fn value(&self) -> u8 { 42 } } fn my_code<S>(source: S) -> u8 where S: ValueSource, { source.value() } #[cfg(test)] mod test { use super::*; struct TestSource(u8); impl ValueSource for TestSource { fn value(&self) -> u8 { self.0 } } #[test] fn one() { let src = TestSource(99); assert_eq!(99, my_code(src)); } }这会将相关细节集中到一个对象中,编译器会对调用进行单态化,从而生成优化的代码.
This will concentrate related details into one object and the compiler monomorphizes the calls, producing optimized code.
- 如何测试标准输入和标准输出?
- 是否有更简洁的方法来测试使用需要用户在 Rust 中输入的函数的函数?
- 有没有办法模拟 Java 行为,即调用父类的静态方法以进行简单的全局错误处理?
更多推荐
有没有办法检测是否正在从 Rust 的测试中调用代码?
发布评论