LocalStack Testing in Clojure

If you are using the v2 AWS SDK clients, you can configure them like so:

(ns my.s3
    (java.net URI)
    (software.amazon.awssdk.regions Region)
    (software.amazon.awssdk.services.s3 S3Client)
    (software.amazon.awssdk.services.s3.model ListBucketsResponse)
    (software.amazon.awssdk.auth.credentials StaticCredentialsProvider AwsBasicCredentials)))

;; The actual client should just read the values from the environment.
;; Never hard-code your credentials.
(defn create-standard-client [] 
    (-> (S3Client/builder)

;; The LocalStack client will need to override the URL and set
;; a region, access key, and secret key even though they are not used.
;; The actual values of the region and keys do not matter.
(defn create-localstack-client []
    (-> (S3Client/builder)
                (AwsBasicCredentials/create "test" "test")))
        (.endpointOverride (URI. "http://localhost:4566"))
        (.region Region/US_EAST_1)

(defn list-buckets [^S3Client s3-client]
  (.listBuckets s3-client))

If you are using Amazonica, you could implement the equivalent like so. Note that for S3 you might have to add :client-config when running against LocalStack. More details are here. With Amazonica, if you omit the creds argument to functions, it will just use the DefaultAWSCredentialsProviderChain. If you prefer to structure your code in such a manner where you inject different clients, you can implement it by getting an instance of the provider chain.

(ns my.s3
    (:require [amazonica.aws.s3 :as s3])
    (:import (com.amazonaws.auth DefaultAWSCredentialsProviderChain)))

;; Not strictly necessary, but will simplify code that injects different clients depending on the context
(defn create-standard-credentials []

(def localstack-credentials
    {:access-key "test"
     :secret-key "test"
     :endpoint "http://localhost:4566"})

(defn list-buckets [creds]
    (s3/list-buckets creds))