lipanski / mockito

HTTP mocking for Rust!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

No longer able to use mockito inside of #[tokio::test]

Yunzlez opened this issue · comments

Since 1.3.1 it is no longer possible to use mockito in async tests (#[tokio::test]):

Cannot start a runtime from within a runtime. This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used to drive asynchronous tasks.

I assume this is related to some of the changes to the use of the Tokio runtime in 1.3.1

Here's a minimal example that works on 1.3.0, but fails with above error on 1.3.1:
cargo.toml

# ...
[dependencies]
mockito = "=1.3.0"
reqwest = "0.11"
tokio = { version = "1.36", features = ["full"] }

mod test:

#[cfg(test)]
mod test {
    use std::fmt::format;
    use reqwest::{Client, Method, StatusCode};

    #[tokio::test]
    async fn test() {
        let mut server = mockito::Server::new();
        let client = Client::new();

        let mock = server
            .mock("GET", "/test")
            .with_status(204)
            .create();

        let res = client.request(Method::GET, format!("{}/test", server.url().as_str()))
            .send()
            .await;

        match res {
            Ok(it) => {
                assert_eq!(it.status(), StatusCode::NO_CONTENT)
            },
            Err(_) => {
                assert!(false, "Response was Err")
            }
        }
    }
}

Turns out I need to RTFM and use the _async methods :) :

#[cfg(test)]
mod test {
    use std::fmt::format;
    use reqwest::{Client, Method, StatusCode};

    #[tokio::test]
    async fn test() {
        let mut server = mockito::Server::new_async().await;
        let client = Client::new();

        let mock = server
            .mock("GET", "/test")
            .with_status(204)
            .create_async().await;

        let res = client.request(Method::GET, format!("{}/test", server.url().as_str()))
            .send()
            .await;

        match res {
            Ok(it) => {
                assert_eq!(it.status(), StatusCode::NO_CONTENT)
            },
            Err(_) => {
                assert!(false, "Unexpected response")
            }
        }
    }

I just wanted to say thank you for filing this issue-- I just accidentally did the same thing as you, called new when I should have called new_async, and a search for "Cannot start a runtime from within a runtime" in this repo quickly brought me to this issue and the solution. I'm sure you'll save lots of people lots of time with this!