Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integer as JSON Response doesn't work #105

Closed
simanacci opened this issue Dec 30, 2022 · 2 comments
Closed

Integer as JSON Response doesn't work #105

simanacci opened this issue Dec 30, 2022 · 2 comments

Comments

@simanacci
Copy link

simanacci commented Dec 30, 2022

Code

[dependencies]
tokio =  { version = "1.23.0", features = [ "full" ] }
wiremock = "0.5.15"
reqwest = { version = "0.11", features = [ "json" ] }
serde = { version = "1.0.147", features = [ "derive" ] }
use serde::{Deserialize, Serialize};
use wiremock::{
    matchers::{self, method},
    Mock, MockServer, ResponseTemplate,
};

#[derive(Serialize, Deserialize, Debug)]
#[serde(transparent)]
struct Max {
    pub max: Option<i32>,
}

#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
struct Config {
    pub max_id_url: String,
}

async fn find_max_id_from_hn(config: Config) -> Result<Option<i32>, reqwest::Error> {
    println!("{:#?}", config);
    let max = reqwest::get(&config.max_id_url)
        .await?
        .json::<Max>()
        .await
        .ok();
    Ok(max.max)
}

#[tokio::main]
async fn main() {
    let map = reqwest::get("https://hacker-news.firebaseio.com/v0/maxitem.json?print=pretty")
        .await
        .unwrap()
        .json::<Max>()
        .await
        .unwrap();
    println!("Actual {:?}", map);

    let mock_server = MockServer::start().await;
    let max_id_url = format!("{}/v0/maxitem.json?print=pretty", mock_server.uri());
    let config = Config { max_id_url };
    let body = Max { max: Some(33)};
    let template = ResponseTemplate::new(200).set_body_json(body);
    Mock::given(method("GET"))
        .and(matchers::path("/v0/maxitem.json?print=pretty"))
        .respond_with(template)
        .mount(&mock_server)
        .await;
    let max = find_max_id_from_hn(config).await.unwrap();
    println!("set_body_json {:?}", max);

    let mock_server = MockServer::start().await;
    let max_id_url = format!("{}/v0/maxitem.json?print=pretty", mock_server.uri());
    let config = Config { max_id_url };
    let template = ResponseTemplate::new(200)
        .set_body_raw(r#"34222111"#.as_bytes().to_owned(), "application/json");
    Mock::given(method("GET"))
        .and(matchers::path("/v0/maxitem.json?print=pretty"))
        .respond_with(template)
        .mount(&mock_server)
        .await;
    let max = find_max_id_from_hn(config).await.unwrap();
    println!("set_body_raw {:?}", max);

    let mock_server = MockServer::start().await;
    let max_id_url = format!("{}/v0/maxitem.json?print=pretty", mock_server.uri());
    let config = Config { max_id_url };
    let template = ResponseTemplate::new(200).set_body_string("34222111");
    Mock::given(method("GET"))
        .and(matchers::path("/v0/maxitem.json?print=pretty"))
        .respond_with(template)
        .mount(&mock_server)
        .await;
    let max = find_max_id_from_hn(config).await.unwrap();
    println!("set_body_string {:?}", max);
}

Output

warning: `playground` (bin "playground") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 4.86s
     Running `target/debug/playground`
Actual Max { max: Some(34189447) }
Config {
    max_id_url: "http://127.0.0.1:35255/v0/maxitem.json?print=pretty",
}
set_body_json None
Config {
    max_id_url: "http://127.0.0.1:45337/v0/maxitem.json?print=pretty",
}
set_body_raw None
Config {
    max_id_url: "http://127.0.0.1:43199/v0/maxitem.json?print=pretty",
}
set_body_string None

Actual result from Hacker News API
https://i.imgur.com/79SJnTX.png

@simanacci simanacci changed the title Integer as JSON Response fails Integer as JSON Response doesn't work Dec 30, 2022
@LukeMathWalker
Copy link
Owner

It's an issue with your matcher - it should be:

    Mock::given(method("GET"))
        // We do NOT include query parameters here
        .and(matchers::path("/v0/maxitem.json"))
        .and(matchers::query_param("print", "pretty"))
        .respond_with(template)
        // [...]

#104 should make this more obvious going forward.

@LukeMathWalker
Copy link
Owner

If you update to wiremock 0.5.16 and run your code again, you'll get this error:

thread 'main' panicked at 'Wiremock can't match the path `/v0/maxitem.json?print=pretty` because it contains a `?`. You must use `wiremock::matchers::query_param` to match on query parameters (the part of the path after the `?`).'

which should be more helpful in nudging you in the right direction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants