#io-stream #stream #mocking #io #test

mockstream

用于在测试中模拟真实流使用的 Stream (Read+Write 特性) 实现

3 个版本

使用旧的 Rust 2015

0.0.3 2017年11月6日
0.0.2 2015年4月6日
0.0.1 2015年2月26日

#236 in 测试

Download history 486/week @ 2024-03-13 339/week @ 2024-03-20 408/week @ 2024-03-27 410/week @ 2024-04-03 216/week @ 2024-04-10 355/week @ 2024-04-17 452/week @ 2024-04-24 430/week @ 2024-05-01 355/week @ 2024-05-08 325/week @ 2024-05-15 174/week @ 2024-05-22 189/week @ 2024-05-29 238/week @ 2024-06-05 385/week @ 2024-06-12 267/week @ 2024-06-19 272/week @ 2024-06-26

1,215 每月下载量
用于 7 crates

MIT 许可证

15KB
279

rust-mockstream

用于在测试中模拟真实流的 Stream (Read+Write 特性) 实现。

安装

只需使用 Cargo。

使用场景

将您使用的流包装到 ADT 中,并提供 Read 和 Write 特性实现。

enum NetStream {
	Mocked(SharedMockStream),
	Tcp(TcpStream)
}

impl io::Read for NetStream {
	fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
		match *self {
			NetStream::Mocked(ref mut s) => s.read(buf),
			NetStream::Tcp(ref mut s) => s.read(buf),
		}
	}
}

impl io::Write for NetStream {
	fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
		match *self {
			NetStream::Mocked(ref mut s) => s.write(buf),
			NetStream::Tcp(ref mut s) => s.write(buf),
		}
	}

	fn flush(&mut self) -> io::Result<()> {
		match *self {
			NetStream::Mocked(ref mut s) => s.flush(),
			NetStream::Tcp(ref mut s) => s.flush(),
		}
	}
}

然后在整个项目中使用这个 ADT 而不是流。

fn reverse4(s: &mut NetStream) -> io::Result<usize> {
	use std::io::{Read, Write};
	
	// read 4 bytes into v
	let mut v = [0; 4];
	let count = try![s.read(v.as_mut_slice())];
	assert_eq!(count, 4);

	// reverse them
	v.reverse();

	// write them back to network
	s.write(v.as_slice())
}

在测试中,提供模拟数据和执行操作后的验证结果。

	let mut s = SharedMockStream::new();
	let mut e = NetStream::Mocked(s.clone());

	// provide data to mock
	s.push_bytes_to_read([1, 2, 3, 4].as_slice());
	// check if io succeeded
	assert_eq!(reverse4(&mut e), Ok(4));
	// verify the data returned
	assert_eq!(s.pop_bytes_written().as_slice(), [4, 3, 2, 1]);

I/O 故障

还提供了模拟 I/O 错误的模拟。结合 Chain,可以模拟读取数据之间的错误。以下示例中,read_data 在 I/O 错误上进行 3 次重试。这已在下面的测试函数中验证。

struct CountIo {}

impl CountIo {
	fn read_data(&self, r: &mut Read) -> usize {
		let mut count: usize = 0;
		let mut retries = 3;

		loop {
			let mut buffer = [0; 5];
			match r.read(&mut buffer) {
				Err(_) => {
					if retries == 0 { break; }
					retries -= 1;
				},
				Ok(0) => break,
				Ok(n) => count += n,
			}
		}
		count
	}
}

#[test]
fn test_io_retries() {
	let mut c = Cursor::new(&b"1234"[..])
			.chain(FailingMockStream::new(ErrorKind::Other, "Failing", 3))
			.chain(Cursor::new(&b"5678"[..]));

	let sut = CountIo {};
	// this will fail unless read_data performs at least 3 retries on I/O errors
	assert_eq!(8, sut.read_data(&mut c));
}

无运行时依赖