Rust 从函数返回惰性静态互斥体的MutexGuard需要一个生存期参数
我正在使用模拟函数编写测试,用Rust 从函数返回惰性静态互斥体的MutexGuard需要一个生存期参数,rust,Rust,我正在使用模拟函数编写测试,用互斥体控制测试中的返回值: #[macro_use] extern crate lazy_static; #[cfg(test)] pub use mock::*; #[cfg(not(test))] pub use real::*; mod real { pub fn say_hello(_name: String) -> String { unimplemented!() } } /// simulate multip
互斥体控制测试中的返回值:
#[macro_use]
extern crate lazy_static;
#[cfg(test)]
pub use mock::*;
#[cfg(not(test))]
pub use real::*;
mod real {
pub fn say_hello(_name: String) -> String {
unimplemented!()
}
}
/// simulate multiple uses, replace `real` in test.
mod mock {
use std::sync::*;
lazy_static! {
pub static ref LOCK: Mutex<bool> = Mutex::new(true);
pub static ref HELLO_VALUE: Mutex<String> = Mutex::new(String::default());
}
pub fn say_hello(_name: String) -> String {
use std::ops::Deref;
HELLO_VALUE.lock().unwrap().deref().clone()
}
pub fn set_hello_return_value(rtn: String) -> MutexGuard<bool> {
let lock = LOCK.lock().unwrap();
let mut value = HELLO_VALUE.lock().unwrap();
*value = rtn;
lock
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test1() {
// repeated block begin--------------------------
let _lock = LOCK.lock().unwrap();
let mut value = HELLO_VALUE.lock().unwrap();
*value = "Hello Tom!".to_string(); // just this line is different from test2
drop(value);
// repeat block end--------------------------
assert_eq!("Hello Tom!", say_hello("".to_string()));
}
#[test]
fn test2() {
// repeated block begin--------------------------
let _lock = LOCK.lock().unwrap();
let mut value = HELLO_VALUE.lock().unwrap();
*value = "Hello Jack!".to_string(); // just this line is different from test1
drop(value);
// repeat block end--------------------------
assert_eq!("Hello Jack!", say_hello("".to_string()));
}
#[test]
fn test_simplified_but_not_work() {
let _lock = set_hello_return_value("Hello Mark!".to_string());
assert_eq!("Hello Mark!", say_hello("".to_string()));
}
}
请帮我更正。阅读完整的错误消息:
考虑给它一个显式的有界生存期或“静态生存期”
这样做可以:
pub fn set_hello_return_value(rtn: String) -> MutexGuard<'static, bool> {
let lock = LOCK.lock().unwrap();
let mut value = HELLO_VALUE.lock().unwrap();
*value = rtn;
lock
}
pub fn set\u hello\u return\u值(rtn:String)->MutexGuard字符串
哪里
G:问候,
{
问候者。说你好(name.into())
}
特质问候语{
fn说你好(&self,name:&str)->String;
}
结构RealGreeting;
impl问候语用于RealGreeting{
fn说你好(&self,name:&str)->String{
格式!(“你好,{}”,名称)
}
}
#[cfg(测试)]
模试验{
使用超级::*;
使用std::cell::RefCell;
结构模拟问候语{
fn新(值:&'a str)->自我{
自我{
价值
使用:Default::Default()调用了_,
}
}
}
恳求{
fn说你好(&self,name:&str)->String{
self.called_with.borrow_mut().push(name.to_owned());
self.value.to_owned()
}
}
#[测试]
fn test1(){
让g=MockGreeting::new(“Hello”);
让r=你使用的东西说你好(&g,“汤姆”);
断言_eq!(“你好,r”);
assert_eq!(&*g.called_with.borrow(),&[“Tom.to_string());
}
}
为什么要返回MutexGuard
类型?若要锁定并避免其他测试以设置可能导致断言错误的值,请不要编辑问题以包含答案。如果你有一些实质性的补充,我们鼓励你把自己的答案贴在下面。但是,您的代码与您接受的答案完全相同。既然你接受了它,这对以后读到这篇文章的人来说已经足够了。我已经从你的问题中删除了这个。太好了,我学了一辈子新语法。谢谢顺便说一下,测试运行良好,但如果我不锁定它们,它们将失败。如果它像你说的那样,如何达到我的目的。我的上帝!你能给我一段示例代码来学习吗。我来自java,我的想法有很多OOconcepts@llxxbbJava完全充满了依赖注入;这不是Rust独有的概念,甚至不是非常新的概念。我加了一张草图,画出了它的样子。通过参数传递所有需要的信息,并模拟必须是Trait
的参数。我误解了依赖项注入,所有注入都必须手动完成,而不是由某些板条箱或其他东西自动完成。再次感谢。
pub fn with_hello_return_value<S, F>(rtn: S, f: F)
where
S: Into<String>,
F: FnOnce(),
{
let _lock = LOCK.lock().unwrap();
*HELLO_VALUE.lock().unwrap() = rtn.into();
f()
}
#[test]
fn test_simplified() {
with_hello_return_value("Hello Mark!", || {
assert_eq!("Hello Mark!", say_hello("".to_string()));
});
}
fn thing_that_uses_say_hello<G>(greeter: &G, name: &str) -> String
where
G: Greeting,
{
greeter.say_hello(name.into())
}
trait Greeting {
fn say_hello(&self, name: &str) -> String;
}
struct RealGreeting;
impl Greeting for RealGreeting {
fn say_hello(&self, name: &str) -> String {
format!("Hello, {}", name)
}
}
#[cfg(test)]
mod test {
use super::*;
use std::cell::RefCell;
struct MockGreeting<'a> {
called_with: RefCell<Vec<String>>,
value: &'a str,
}
impl<'a> MockGreeting<'a> {
fn new(value: &'a str) -> Self {
Self {
value,
called_with: Default::default(),
}
}
}
impl<'a> Greeting for MockGreeting<'a> {
fn say_hello(&self, name: &str) -> String {
self.called_with.borrow_mut().push(name.to_owned());
self.value.to_owned()
}
}
#[test]
fn test1() {
let g = MockGreeting::new("Hello");
let r = thing_that_uses_say_hello(&g, "Tom");
assert_eq!("Hello", r);
assert_eq!(&*g.called_with.borrow(), &["Tom".to_string()]);
}
}