I have a struct that works as a postmaster for a server application: since I don't know how many clients will connect I have the postmaster listen on a socket and start a new struct with business logic whenever a client opens a connection.
But this means I don't know how to implement integration tests for the Postmaster. There is a public "main" method that hangs indefinitely while waiting for connections:
#[tokio::main]
pub async fn start(self) -> Result<(), GenericError> {
// https://stackoverflow.com/a/55874334/70600
let mut this = self;
loop {
let tmp = this.configuration.clone().hostaddr();
println!("{:?}", tmp);
let listener = TcpListener::bind(tmp).await?;
match listener.accept().await {
Ok((stream, _addr)) => {
let backend = Backend::new(&this.configuration, stream);
this.backends.push(backend);
}
Err(e) => todo!("Log error accepting client connection."),
}
}
Ok(())
}
This is my test:
#[test]
fn test_server_default_configuration() {
let postmaster = Postmaster::default();
let started = postmaster.start();
assert!(started.is_ok())
}
Except the assert is obviously never reached. How can I test this async code?
You can start the postmaster in a separate thread, connect to it, and give it some commands, and check the responses:
#[test]
fn test_server_default_configuration() {
let postmaster = Postmaster::default();
let thr = std::thread::spawn(move || postmaster.start());
// connect to the configured address, test the responses...
// ...
// finally, send the postmaster a "quit" command
let result = thr.join().unwrap();
assert!(result.is_ok())
}
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