Existe uma maneira mais limpa de testar funções que usam funções que exigem entrada do usuário no Rust?

Estou escrevendo umBiblioteca de perguntas da CLI para o meu primeiro projeto Rust, pois provavelmente o utilizarei de qualquer maneira e não consigo encontrar uma maneira limpa de testar oterminal método do padrão do construtor, que usando a configuração obtém entrada do usuário e retorna uma resposta.

pub fn confirm(&mut self) -> Answer {
    self.yes_no();
    self.build_prompt();
    let prompt = self.prompt.clone();
    let valid_responses = self.valid_responses.clone().unwrap();
    loop {
        let stdio = io::stdin();
        let input = stdio.lock();
        let output = io::stdout();
        if let Ok(response) = prompt_user(input, output, &prompt) {
            for key in valid_responses.keys() {
                if *response.trim().to_lowercase() == *key {
                    return valid_responses.get(key).unwrap().clone();
                }
            }
            self.build_clarification();
        }
    }
}

Procurando uma solução que eu descobriInjeção de dependência o que me permitiu escrever testes para a função que solicita a entrada do usuário usandoCursor. Não me permite alterar a entrada do usuário para aconfirm() função para cada teste deQuestion::new("Continue?").confirm() no entanto, tentei usar a compilação condicional e criei o seguinte.

#[cfg(not(test))]
fn prompt_user<R, W>(mut reader: R, mut writer: W, question: &str) -> Result<String, std::io::Error>
where
    R: BufRead,
    W: Write,
{
    write!(&mut writer, "{}", question)?;
    let mut s = String::new();
    reader.read_line(&mut s)?;
    Ok(s)
}

#[cfg(test)]
fn prompt_user<R, W>(mut reader: R, mut writer: W, question: &str) -> Result<String, std::io::Error>
where
    R: BufRead,
    W: Write,
{
    use tests;
    Ok(unsafe { tests::test_response.to_string() })
}

E notests módulo eu uso uma variável global:

pub static mut test_response: &str = "";

#[test]
fn simple_confirm() {
    unsafe { test_response = "y" };
    let answer = Question::new("Continue?").confirm();
    assert_eq!(Answer::YES, answer);
}

Isso funciona desde que eu execute apenas testes com um único thread, mas também não me permita mais testar a função real de entrada do usuário. Não é realmente um problema para uma caixa tão pequena, mas é muito confusa. Não vi nenhuma solução para fazer isso em nenhuma biblioteca de teste disponível.

questionAnswers(1)

yourAnswerToTheQuestion