Testing 如何在不要求参数函数可变的情况下测试元函数?

Testing 如何在不要求参数函数可变的情况下测试元函数?,testing,rust,automated-tests,higher-order-functions,Testing,Rust,Automated Tests,Higher Order Functions,我编写了一个函数save,它将函数作为参数: fn保存方法:&dyn fn&'static str{ 方法你好世界; } fn printstring:&'static str{ println!{},字符串; } fn干线{ 保存和打印 } 这太棒了!但我现在想测试save。我认为最好的方法是使用FnMut: fn savemethod:&mut dyn FnMut&'static str{ 方法你好世界; } fn printstring:&'static str{ println!{},字

我编写了一个函数save,它将函数作为参数:

fn保存方法:&dyn fn&'static str{ 方法你好世界; } fn printstring:&'static str{ println!{},字符串; } fn干线{ 保存和打印 } 这太棒了!但我现在想测试save。我认为最好的方法是使用FnMut:

fn savemethod:&mut dyn FnMut&'static str{ 方法你好世界; } fn printstring:&'static str{ println!{},字符串; } fn干线{ 保存和多打印 } [cfgtest] 模试验{ 使用超级::*; [测试] 保存测试{ 设实际={ 让mut-actual=String::new; 让mut方法=|字符串:&'static str|{ 实际值=格式!{}{},实际值,字符串; }; save&mut方法; save&mut方法; 真实的 }; let expected=Hello world Hello world.to_字符串; 断言_eq!实际,预期; } } 这仍然有效,实现了我想要的一切!但是现在每当我调用save时,我必须使用可变引用。虽然这不会影响功能,但会混淆代码。有没有更好的方法来达到同样的效果?

只需在内部断言:

fn保存方法:impl fn&'static str{ 方法你好世界; } [测试] 保存测试{ 让我们检查=|结果|{ 断言eq!结果,你好,世界; }; 储蓄支票; 储蓄支票; } 不能确保函数是调用的,这是一种折衷办法

只需在内部断言即可:

fn保存方法:impl fn&'static str{ 方法你好世界; } [测试] 保存测试{ 让我们检查=|结果|{ 断言eq!结果,你好,世界; }; 储蓄支票; 储蓄支票; } 不能确保函数是调用的,这是一种折衷,您可以使用它来获得内部可变性,允许您通过共享引用来可变变量。它非常适合测试以下内容:

[cfgtest] 模试验{ 使用std::cell::RefCell; 使用超级::*; [测试] 保存测试{ 设实际={ //在RefCell中包裹实际值,这允许内部可变 让actual=RefCell::newString::new; let方法=|字符串:&'static str|{ //在运行时可变地借用字符串 //可以在已经借来的地方恐慌,但这里不是问题 让mut-actual=actual.borrow\u-mut; //附加与您的格式相同的字符串!但可以更多 //有效的 实际推送字符串; }; 保存方法; 保存方法; //将字符串移出参照单元格 实际的 }; let expected=Hello world Hello world.to_字符串; 断言_eq!实际,预期; } } 您可以使用获取内部可变性,允许您通过共享引用对变量进行可变性。它非常适合测试以下内容:

[cfgtest] 模试验{ 使用std::cell::RefCell; 使用超级::*; [测试] 保存测试{ 设实际={ //在RefCell中包裹实际值,这允许内部可变 让actual=RefCell::newString::new; let方法=|字符串:&'static str|{ //在运行时可变地借用字符串 //可以在已经借来的地方恐慌,但这里不是问题 让mut-actual=actual.borrow\u-mut; //附加与您的格式相同的字符串!但可以更多 //有效的 实际推送字符串; }; 保存方法; 保存方法; //将字符串移出参照单元格 实际的 }; let expected=Hello world Hello world.to_字符串; 断言_eq!实际,预期; } }
这对于很多情况都是一个很好的答案,包括我提供的pet示例。我接受了另一个答案,因为它更普遍适用,并且是我在代码中实际使用的。特别是,我的代码中的实际save函数用于与MySql数据库交互。它的方法参数(每次调用多次以保存)将插入查询作为输入并返回结果行的主id。因此,存根检查需要能够验证不同的插入查询并增加其返回的id。这对于很多情况都是一个很好的答案,包括我提供的pet示例。我接受了另一个答案,因为它更普遍适用,并且是我在代码中实际使用的。特别是,我的代码中的实际save函数用于与MySql数据库交互。其方法参数(每次调用多次以保存)将插入查询作为输入并返回结果行的主id。因此,存根检查需要能够验证不同的插入查询并增加其返回的id。