Help with Integration test with actix-web

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

You're binding to 127.0.0.0 but all your other code is using 127.0.0.1

Thank You very much. can't believed i missed that. thanks test passing now

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.