Fork me on GitHub
#aws
<
2020-06-16
>
souenzzo13:06:33

there is some lib/docs about how to reify / mock aws clients?

dchelimsky16:06:21

Do you mean in aws-api?

dchelimsky16:06:15

Assuming you do, there is no specific support for doing that, so no docs. What are you trying to do?

souenzzo16:06:09

I started with (aws/invoke (reify .... {:successId 42}) {:op :DoThing}) ;;=> {:successId 42} and I see that it's possible to mock out everything but i ran out of time I will try again this night. tnks 🙂

dchelimsky19:06:35

I still don't understand what you're trying to do. Why not just use a client as/is? Is this for testing?

souenzzo19:06:24

Yep, for "offline" testing

dchelimsky21:06:54

Why not just use with-redefs?

dchelimsky21:06:27

I'm assuming that you're reifying ClientSPI, but that's internal and subject to (read: likely to) change. Until there's a documented seam for what you're doing you'll be safer with with-redefs (unless you're tests are concerned w/ thread safety, in which case 🤷 ).

Ben Sless14:07:22

Bit late but you can mock the http client api more easily, make sure to return an anomaly. Take a look at the tests for reference

dchelimsky14:07:55

That’s all internal as well. We’re working on a test double client (avoiding the word mock because we’re not going to explicitly support verification).

Ben Sless15:07:24

Unfortunately since there's no support for testing or documentation of the APIs in use, users must fend for themselves

Ben Sless15:07:16

Even something like "here's how you should test your code when using the library"

dchelimsky22:08:03

We’re working on something that looks like this right now.

(require '[cognitect.aws.client.test :as test]
         '[cognitect.aws.client.api :as aws])

;; implementation being tested
(defn do-something [s3-client]
  ;; if :response is bound to a value, invoke will return that value
  ;; if :response is bound to a funtion, invoke will return the return
  ;;    of that function
  (let [res (aws/invoke s3-client {:op :CreateBucket
                                   :request {:Bucket "a-bucket"}})]
    ;; do stuff with res
    ))

;; test using a stub
(let [test-s3-client (test/client {:api :s3})]
  (test/stub test-s3-client
             {:op :ListBuckets
              :response {:Location "a-location"}})
  (let [res (do-something test-s3-client)]
    ;; make assertions about res
    ))

;; test using a handler function
(let [test-s3-client (test/client {:api :s3})]
  (test/stub test-s3-client
             {:op :ListBuckets
              ;; op-map is the 2nd argument to `invoke`
              :response (fn [op-map]
                          ;; do stuff based on op-map
                          ;; then, return a value
                          {:Location "def"})})
  (let [res (do-something test-s3-client)]
    ;; make assertions about res
    ))
In most cases, we’d expect that folks would just stub return values, but for those who want more interaction based tests (mocks, spies, etc), the functions let you implement whatever you want. Also, this is based on a new Client protocol with invoke and stop, that you can reify yourself and do whatever you want with. Thoughts? This is in progress now and subject to change, so any feedback would be most appreciated.

dchelimsky22:08:49

Actually, I just copied all that to a https://github.com/cognitect-labs/aws-api/issues/186#issuecomment-1205848703. Please respond there so we more easily find the conversation later.

dchelimsky23:08:39

cc: @UK0810AQ2 @U2J4FRT2T (sorry for the noise - but just want to make sure you see this - no urgency)

souenzzo23:08:01

lgtm. Out of curiosity: why not test-s3-client (test/client {:api :s3 :stub (fn [op-map] ...)}) ? It would allow us to, for example, create things like :stub (in-memory-s3) or :stub (fs-s3 (io/file "..."))

dchelimsky23:08:43

How would that handle different s3 ops? i.e. if you invoke :ListBuckets and :CreateBucket in the course of the same test.

dchelimsky23:08:40

Of course, now that there will be a protocol, you can reify it any way you like.

dchelimsky12:08:07

I guess we could do it this way:

(test/client {:api :s3 :stubs {:ListBuckets {:Buckets [{:Name "bucket-1"}]} 
                               :CreateBucket (fn [op-map] ,,,)}})
That forces you to set up everything for a test at once, which is less error prone than making it stateful (i.e. registering stubs/handlers one at a time). And sure, you could implement an entire in-memory s3 as a map of operations to functions of op-map, but now you’re risking false positives by implementing behavior inconsistent with AWS. I’d stick to literal return values as much as possible.

👍 1
dchelimsky20:09:01

The test client is on the `mcrmc/test-client` branch of https://github.com/cognitect-labs/aws-api. If you’d like to try it out,

git clone [email protected]:cognitect-labs/aws-api.git
git co mcrmc/test-client
Now you can include it in a local project with {:deps {com.cognitect.aws/api {:local/root "<path to aws-api directory>"}} Doc is on that branch: https://github.com/cognitect-labs/aws-api/blob/mcrmc/test-client/doc/testing.md

dchelimsky22:09:33

Posting this to the channel in case anybody is interested and hasn’t seen this thread. We’re getting ready to release aws-api with a test double client that you can instrument to respond to invoke and invoke-async(new) however you see fit for your test without any AWS account, internet access, configuration, etc, outside the test. If this sounds interesting to you, please

git clone [email protected]:cognitect-labs/aws-api.git
git co mcrmc/test-client
And then add {:deps {com.cognitect.aws/api {:local/root "<path to aws-api directory>"}} to your deps.edn (or you can mvn install and then include the “DEV” version in deps.edn or leiningen project.clj). Docs are here, on the branch: https://github.com/cognitect-labs/aws-api/blob/mcrmc/test-client/doc/testing.md Please provide feedback on https://github.com/cognitect-labs/aws-api/issues/186. Thanks!!!!

👏 6
1
1
dchelimsky10:09:07

Released in version 0.8.589. I’ll send out a more complete announcement later today.

dchelimsky12:10:45

I'm curious to know if anybody has been using the new test-double feature and how it's working for you?

souenzzo16:10:02

I'm using it with S3 API to run in-memory tests in my app. It is a webservice + worker, that may turn into a SaaS when I have time

dchelimsky14:10:47

And it's working well for you? Any issues?

dchelimsky22:09:33

Posting this to the channel in case anybody is interested and hasn’t seen this thread. We’re getting ready to release aws-api with a test double client that you can instrument to respond to invoke and invoke-async(new) however you see fit for your test without any AWS account, internet access, configuration, etc, outside the test. If this sounds interesting to you, please

git clone [email protected]:cognitect-labs/aws-api.git
git co mcrmc/test-client
And then add {:deps {com.cognitect.aws/api {:local/root "<path to aws-api directory>"}} to your deps.edn (or you can mvn install and then include the “DEV” version in deps.edn or leiningen project.clj). Docs are here, on the branch: https://github.com/cognitect-labs/aws-api/blob/mcrmc/test-client/doc/testing.md Please provide feedback on https://github.com/cognitect-labs/aws-api/issues/186. Thanks!!!!

👏 6
1
1
dchelimsky12:10:45

I'm curious to know if anybody has been using the new test-double feature and how it's working for you?