当我检查File::set_len(..)
时,它看起来像是为struct File
实现的,但不是通过Trait实现的。
目标:测试foo
,它以读/写方式打开文件,执行以下操作:读,写,查找,并修剪文件到一定的大小。我们喜欢在测试中提供文件的初始状态,并检查结果。最好是在内存中。
如何测试依赖于set_len
的代码?(io::Seek
或其他特性目前没有帮助)。
我想嘲笑它。
让我们举一个玩具例子,让讨论更容易:
#![allow(unused_variables)]
use std::error::Error;
use std::fs::File;
use std::io::Cursor;
// assumes that file is open in Read/Write mode
// foo performs reads and writes and Seeks
// at the end wants to trim size of file to certain size.
fn foo(f: &mut File) -> Result<(), Box<dyn Error>> {
f.set_len(0)?;
Ok(())
}
fn main () -> Result<(), Box<dyn Error>> {
let mut buf = Vec::new();
let mut mockfile = Cursor::new(&buf);
// we would like to supply foo
// with "test" representation of initial file state
foo(&mut mockfile)
// and check afterwards if resulting contents (=> size)
// of file match expectations
}
关于生 rust :https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=950a94504168d51f043966288fae3bca
错误:
error[E0308]: mismatched types
--> src/main.rs:15:9
|
15 | foo(&mut mockfile)
| ^^^^^^^^^^^^^ expected struct `File`, found struct `std::io::Cursor`
P.S.在收到答案之前,我开始尝试tempfile
板条箱:尽管https://docs.rs/tempfile/3.1.0/tempfile/#structs如此,理想的解决方案还是“内存中”,所以不能等待问题的答案:)。
1条答案
按热度按时间iqxoj9l91#
简而言之,如果一个函数需要
std::fs::File
的确切类型,就不能模拟std::fs::File
--这不是Rust的工作方式。但是,如果您可以控制
foo
,那么您可以轻松地发明一个具有set_len
的特征,并使foo
泛型化。(例如File
),这将使foo()
像以前一样接受File
,但它也将接受实现该特征的任何其他内容,包括你在测试套件中创建的mock类型。2并且由于单态化,它的执行将和原始代码一样高效。3例如:要模拟它,只需定义一个实现该特征的类型,并记录它是否被调用:
Playground