How do I test asynchronous code? I'm getting by with a mutable flag but man is this test ugly. I was wondering if there are any best practices for doing this sort of thing, I'm open to using a new library as well - but I'd prefer to do it all with std
if possible.
The client and server are provided by the ws-rs
library.
#[cfg(test)]
mod tests {
use std::sync::{Arc, Mutex, MutexGuard};
use std::sync::mpsc::channel;
use std::thread;
use crate::components::{Player, Position};
use crate::message::PositionMessage;
use crate::wsserver;
struct Flag(bool);
struct Client <'a> {
out: ws::Sender,
received: MutexGuard<'a, Flag>
}
impl <'a> ws::Handler for Client <'a> {
fn on_message(&mut self, _: ws::Message) -> Result<(), ws::Error> {
self.received.0 = true;
self.out.close(ws::CloseCode::Normal)
}
}
#[test]
fn send_server_position_message() {
let (position_message_sender, position_message_receiver) = channel();
let (input_message_sender, _) = channel();
thread::Builder::new()
.name("Websockets Server".to_owned())
.spawn(move || { wsserver::main(position_message_receiver, input_message_sender) })
.unwrap();
let flag = Arc::new(Mutex::new(Flag(false)));
let flag_clone = flag.clone();
let client = thread::spawn(move || {
let flag = flag.clone();
ws::connect("ws://127.0.0.1:8081", |out| {
Client { out, received: flag.lock().unwrap() }
}).unwrap();
});
position_message_sender.send(PositionMessage {
player: Player { id: 0 },
position: Position { x: 0.0, y: 0.0 }
}).unwrap();
client.join().unwrap();
assert!(flag_clone.lock().unwrap().0);
}
}