2015-02-06 4 views
5

전달 된 문자열을 stdout으로 보내고 stdin에서 읽는 문자열을 반환하는 프롬프트 함수를 작성하고 싶습니다. 어떻게 테스트 할 수 있습니까? 여기stdin과 stdout을 어떻게 테스트 할 수 있습니까?

fn prompt(question: String) -> String { 
    let mut stdin = BufferedReader::new(stdin()); 
    print!("{}", question); 
    match stdin.read_line() { 
     Ok(line) => line, 
     Err(e) => panic!(e), 
    } 
} 

그리고 내 테스트를 시도

#[test] 
fn try_to_test_stdout() { 
    let writer: Vec<u8> = vec![]; 
    set_stdout(Box::new(writer)); 
    print!("testing"); 
// `writer` is now gone, can't check to see if "testing" was sent 
} 

답변

4

사용 종속성 주입입니다 : 여기

함수의 예입니다. 제네릭과 단사 사상과 커플 링하는 것은, 당신이 어떤 성능 손실되지 않습니다 : IO는 매우 그대로

use std::io::{self, BufRead, Write}; 

fn prompt<R, W>(mut reader: R, mut writer: W, question: &str) -> String 
where 
    R: BufRead, 
    W: Write, 
{ 
    write!(&mut writer, "{}", question).expect("Unable to write"); 
    let mut s = String::new(); 
    reader.read_line(&mut s).expect("Unable to read"); 
    s 
} 

#[test] 
fn test_with_in_memory() { 
    let input = b"I'm George"; 
    let mut output = Vec::new(); 

    let answer = prompt(&input[..], &mut output, "Who goes there?"); 

    let output = String::from_utf8(output).expect("Not UTF-8"); 

    assert_eq!("Who goes there?", output); 
    assert_eq!("I'm George", answer); 
} 

fn main() { 
    let stdio = io::stdin(); 
    let input = stdio.lock(); 

    let output = io::stdout(); 

    let answer = prompt(input, output, "Who goes there?"); 
    println!("was: {}", answer); 
} 

많은 경우를, 당신은 실제로 expect을 사용하는 대신 호출자까지 오류를 전파 할 것 실패 할 일반적인 장소.

use std::io::{self, BufRead, Write}; 

struct Quizzer<R, W> { 
    reader: R, 
    writer: W, 
} 

impl<R, W> Quizzer<R, W> 
where 
    R: BufRead, 
    W: Write, 
{ 
    fn prompt(&mut self, question: &str) -> String { 
     write!(&mut self.writer, "{}", question).expect("Unable to write"); 
     let mut s = String::new(); 
     self.reader.read_line(&mut s).expect("Unable to read"); 
     s 
    } 
} 

#[test] 
fn test_with_in_memory() { 
    let input = b"I'm George"; 
    let mut output = Vec::new(); 

    let answer = { 
     let mut quizzer = Quizzer { 
      reader: &input[..], 
      writer: &mut output, 
     }; 

     quizzer.prompt("Who goes there?") 
    }; 

    let output = String::from_utf8(output).expect("Not UTF-8"); 

    assert_eq!("Who goes there?", output); 
    assert_eq!("I'm George", answer); 
} 

fn main() { 
    let stdio = io::stdin(); 
    let input = stdio.lock(); 

    let output = io::stdout(); 

    let mut quizzer = Quizzer { 
     reader: input, 
     writer: output, 
    }; 

    let answer = quizzer.prompt("Who goes there?"); 
    println!("was: {}", answer); 
} 
:


방법으로기능을 넘어 확장 될 수있다

관련 문제