Good day everyone,
Please i need assistance with integration test with actix-web. I recently finished reading the book "Zero to Production in rust by Luca Palmeiri" and decided to use similar method used for the integration test. The code runs fine and works fine but went running integration the server does not accept connection.
Below is the code
Main::
use oneviewcondo::run;
use std::net::TcpListener;
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
// for now we will use hard coded listening url
let listener: TcpListener = TcpListener::bind("127.0.0.1:8080")?;
run(listener)?
.await?;
Ok(())
}
RUN::
use crate::health::health_check;
use actix_web::{dev::Server, web, App, HttpRequest, HttpServer, Responder};
use std::net::TcpListener;
/// start the listening server
pub fn run(listener: TcpListener) -> std::io::Result<Server> {
let server = HttpServer::new(|| {
App::new()
.route("/", web::get().to(index))
.route("/health", web::get().to(health_check))
})
.listen(listener)?
.run();
Ok(server)
}
async fn index(_req: HttpRequest) -> impl Responder {
"hello world"
}
helper method::
use oneviewcondo::run;
use std::net::TcpListener;
// spawn server on another green thread return url to the server
// running on the same local host
pub fn spawn_app() -> String {
let listener: TcpListener = TcpListener::bind("127.0.0.0:8080").unwrap();
let port_number = listener.local_addr().unwrap().port();
let server = run(listener).expect("Unable to run application");
// spawn server in background task
let _ = tokio::spawn(server);
format!("http://127.0.0.1:{}", port_number)
}
TEST::
#[actix_rt::test]
async fn health_check_returns_success() {
let _app_address: String = spawn_app();
let url: String = format!("{}/health", "http://127.0.0.1:8080");
let client: reqwest::Client = reqwest::Client::new();
let resp: reqwest::Response = client.get(url)
.send()
.await
.expect("Failed to connect to the health check endpoint");
let health_status: HealthCheck = resp.json::<HealthCheck>()
.await
.expect("Error parse health check return value to Health Check struct");
assert!(health_status.healthy)
}
Error::
➜ oneviewcondo git:(master) ✗ cargo nextest run
Compiling oneviewcondo v0.1.0 (/home/blackdante/Development/projects/oneviewcondo)
Finished test [unoptimized + debuginfo] target(s) in 5.30s
Starting 2 tests across 5 binaries
PASS [ 0.003s] oneviewcondo::health_check always_succeed
FAIL [ 0.013s] oneviewcondo::health_check health_check_returns_success
--- STDOUT: oneviewcondo::health_check health_check_returns_success ---
running 1 test
test health_check_returns_success ... FAILED
failures:
failures:
health_check_returns_success
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.01s
--- STDERR: oneviewcondo::health_check health_check_returns_success ---
thread 'health_check_returns_success' panicked at 'Failed to connect to the health check endpoint: reqwest::Error { kind: Request, url: Url { scheme: "http", cannot_be_a_base: false, username: "", password: None, host: Some(Ipv4(127.0.0.1)), port: Some(8080), path: "/health", query: None, fragment: None }, source: hyper::Error(Connect, ConnectError("tcp connect error", Os { code: 111, kind: ConnectionRefused, message: "Connection refused" })) }', tests/health_check.rs:15:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Canceling due to test failure: 0 tests still running
------------
Summary [ 0.013s] 2 tests run: 1 passed, 1 failed, 0 skipped
FAIL [ 0.013s] oneviewcondo::health_check health_check_returns_success
error: test run failed
➜ oneviewcondo git:(master) ✗
i even added a small block of code to slow down the test, i can see using the ss command on linux that the server is listening and on localhost:8080 but nothing can connect to the endpoint even using curl command, same with the browser. but running the code directly using cargo run everything works fine both using curl and the browser
Please reach out to me if you have any more question