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

[request]: Ability to mock *::Client #199

Closed
NickLarsenNZ opened this issue Aug 19, 2021 · 8 comments
Closed

[request]: Ability to mock *::Client #199

NickLarsenNZ opened this issue Aug 19, 2021 · 8 comments
Labels
feature-request A feature should be added or improved. p2 This is a standard priority issue

Comments

@NickLarsenNZ
Copy link

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue, please leave a comment

Tell us about your request
Some way of being able to mock the Clients

Tell us about the problem you're trying to solve. What are you trying to do, and why is it hard?
In a contrived piece of code, I'm trying to list EC2 instances - but I'd like to test this offline by mocking the aws_sdk_ec2::Client.

Are you currently working around this issue?
I'm not (just using a real account, and weakening my test assertions).

Additional context
I wondered if there should be some traits to make mocking portions of the Clients easier.

@NickLarsenNZ NickLarsenNZ added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Aug 19, 2021
@rcoh
Copy link
Contributor

rcoh commented Aug 19, 2021

hello! is it just one request you're making? It's possible to swap out the entire HTTP connection used by the client for one that returns canned responses.

Here's an example where we do this to test the KMS client: https://github.com/awslabs/aws-sdk-rust/blob/main/sdk/kms/tests/integration.rs#L24-L49

Note that assuming you don't care about the request being made, you don't need to fill out the request in test connection, it just gets ignored.

To grab the response body, you can turn on trace logging:

// in your main function:
tracing_subscriber::fmt::init();

then:

RUST_LOG='smithy_http=trace' cargo run

I should also add that you can build your own more complex test connections (eg. to pass requests through except for the request you care about). The key piece is the tower service implementation: https://github.com/awslabs/aws-sdk-rust/blob/main/sdk/smithy-client/src/test_connection.rs#L117-L141

Just make sure that your type implements clone.

@rcoh
Copy link
Contributor

rcoh commented Aug 19, 2021

I'll keep this issue open as a place to track work on the general topic of testing code using the SDK

@rcoh rcoh removed the needs-triage This issue or PR still needs to be triaged. label Aug 19, 2021
@phyber
Copy link

phyber commented Aug 24, 2021

I'm using something along these lines to successfully mock client calls, it's not the best example but hopefully you get the idea.
I call this at the beginning of a test to get a client with the responses I want, then I call the client as usual.

    // S3Config and S3Client are aliases to the AWS SDK since I already
    // had structs called Client and Config
    fn mock_client(data_files: Vec<&str>) -> Client {
        let creds = Credentials::from_keys(
            "ATESTCLIENT",
            "atestsecretkey",
            Some("atestsessiontoken".to_string()),
        );

        let conf = S3Config::builder()
            .credentials_provider(creds)
            .region(aws_sdk_s3::Region::new("eu-west-1"))
            .build();

        // Get a vec of events based on the given data_files
        let events = data_files
            .iter()
            .map(|d| {
                let path = Path::new("test-data").join(d);
                let data = fs::read_to_string(path).unwrap();

                // Events
                (
                    // Request
                    http::Request::builder()
                        .body(SdkBody::from("request body"))
                        .unwrap(),

                    // Response
                    http::Response::builder()
                        .status(200)
                        .body(SdkBody::from(data))
                        .unwrap(),
                )
            })
            .collect();

        let conn = TestConnection::new(events);
        let conn = DynConnector::new(conn);
        let client = S3Client::from_conf_conn(conf, conn);

        // My client is wrapped with other things for various reasons.
        Client { client }
    }

The data files here are XML files with API responses that I want to test against, they live in a test-data directory at the root of the crate.

@Fishrock123
Copy link

@phyber How do you access DynConnection and what is TestConnection?

Would be curious to see what that code needs for 0.2

@rcoh
Copy link
Contributor

rcoh commented Dec 6, 2021

TestConnection is in aws-smithy-client gated behind the test-util feature, DynConnector is also in aws-smithy-client

@phyber
Copy link

phyber commented Dec 6, 2021

@phyber How do you access DynConnection and what is TestConnection?

Would be curious to see what that code needs for 0.2

Sorry for not including the use statements with that. As rcoh says, they're in aws_smithy_client.

    use aws_smithy_client::erase::DynConnector;
    use aws_smithy_client::test_connection::TestConnection;

My test code didn't change much after an upgrade to 0.2, just a few minor changes related to Credentials::from_keys (enabling the feature so I could keep the same test code, static keys used only in tests, not in the real code), and the various DateTime stuff so I could convert to/from chrono types.

@jmklix jmklix added the p2 This is a standard priority issue label Nov 28, 2022
@rcoh
Copy link
Contributor

rcoh commented Apr 24, 2024

This is now well supported by aws-smithy-mocks-experimental please give it a try!

@rcoh rcoh closed this as completed Apr 24, 2024
Copy link

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved. p2 This is a standard priority issue
Projects
None yet
Development

No branches or pull requests

5 participants