¿Existe una forma más limpia de probar funciones que utilizan funciones que requieren la entrada del usuario en Rust?

Estoy escribiendo unPregunta CLI preguntando biblioteca para mi primer proyecto Rust ya que probablemente lo usaré de todos modos, y no puedo encontrar una manera limpia de probar elterminal método del patrón de construcción, que mediante la configuración obtiene la entrada del usuario y devuelve una respuesta.

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();
        }
    }
}

Buscando una solución descubríinyección de dependencia lo que me permitió escribir pruebas para la función que solicita al usuario que ingrese usandoCursor. No me permite cambiar la entrada del usuario a laconfirm() función para cada prueba deQuestion::new("Continue?").confirm() aunque intenté usar la compilación condicional y se me ocurrió lo siguiente.

#[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() })
}

Y en eltests módulo uso una variable 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);
}

Esto funciona siempre que solo ejecute pruebas con un solo subproceso, pero ya no me permite probar la función de entrada real del usuario. Realmente no es un problema para una caja tan pequeña, pero es muy desordenada. No vi ninguna solución para hacer esto desde ninguna biblioteca de prueba disponible.

Respuestas a la pregunta(1)

Su respuesta a la pregunta