I have a function that takes an input stream, processes its data, and then returns something, basically a more complicated version of this:
fn read_number_from_stream(input: &mut io::BufRead) -> io::Result<u32> {
// code that does something useful here
Ok(0)
}
Now I want to write a test for this function.
#[test]
fn input_with_zero_returns_zero() {
let test_input = read_from_string("0\n");
assert_eq!(Ok(0), read_number_from_stream(test_input));
}
How do I implement read_from_string
? Older versions of Rust apparently provided std::io::mem::MemReader
, but the entire std::io::mem
module seems to be gone in more recent versions of Rust (I'm using the unstable 1.5 branch).
The documentation for each trait lists the available implementations. Here's the documentation page for BufRead
. We can see that &'a [u8]
(a slice of bytes) implements BufRead
. We can obtain a slice of bytes from a string and pass a mutable reference to that slice to read_number_from_stream
:
use std::io;
fn read_number_from_stream(input: &mut io::BufRead) -> io::Result<u32> {
// code that does something useful here
Ok(0)
}
fn read_from_string(s: &str) -> &[u8] {
s.as_bytes()
}
fn main() {
let mut test_input = read_from_string("0\n");
read_number_from_stream(&mut test_input);
}
If the buffer is not expected to contain UTF-8, or you just care about a particular ASCII-compatible subset of characters, you may want to define the test input as a byte string, rather than as a normal string. A byte string is written like a normal string, prefixed with b
, e.g. b"0\n"
. The type of a byte string is &[u8; N]
, where N
is the length of the string. Since that type doesn't implement BufRead
, we need to cast it to &[u8]
.
fn main() {
let mut test_input = b"0\n" as &[u8];
read_number_from_stream(&mut test_input);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With