Fork me on GitHub

I've just watched a cool talk: "Side Effects are a Public API" by Christopher Armstrong. It's about using free monad for testing side-effects. I've just thought, is there a more accessible way to do this? Would be cool to have spec for side-effects. here it is:


Honestly, everytime I use any technique to make it easier to test side-effects, I feel I'm not testing what I want to test. So it's better to either don't test at all, or just swallow it and test the side effect indeed, maybe even on a different test suite...


@U3Y18N0UC, could you elaborate, please, what you mean by testing the side effect and/or different test suite


For example, if my code needs to hit the database, I wrap everything around something like (with-transaction-rollback [db test-db] (run-my-code db))


Like, it'll open a transaction on DB, make everything it needs to be done, and rollback everything on the end of it


If I need to test some side-effect like a HTTP handler or something, I will either use ring-mock to really dispatch the request as if it was a real HTTP interaction, or I'll open up a server to dispatch it


If my app needs to query some external system, I may use clj-http to "record" real interactions to the external system, instead of mocking results


Once I had to interact with a SFTP and Windows Share servers (and the logic was completely tied to these services). I opened up both services as a docker containers and ran tests with it. This last one was HARD because tests became slow, but every other alternative got us into so many stupid bugs that we ended up firing up these services instead. As tests became slower, we decided on a hiccup-like protocol: [:sftp/list-files "a*"] for example, that would return a vector of filenames, and then we could decide what to do and emit a [:sftp/upload "file-name" "contents"] or [:sftp/rename "old-file" "new-file"] We ended up using this "protocol" as a way to test logic, and we just tested (again, with a REAL sftp and windows share) that, provided this protocol, the app would do the right thing (upload indeed a file, etc). This worked way better and we ended up tagging these tasts as "integration" and we filtered then on our local machine, but made them always run on CI


@U3Y18N0UC, oh, it seems like the follow-up I wrote in the chat is about something similar to what you do, am I right?


Follow-up to the question above: I found an interesting library in scala, it's called auditspec, and it basically logs all mock side-effects that happened, and then compares to what was intended to happen. Here's a blog post about it:


@alexander.scherbanov_: a pretty usual setup is to use Component/Integrant/... and provide test-specific implementations for a given protocol (normally your protocols, but also possibly libraries' protocols) Said implementations can have an atom registering the calls that it received in this issue's readme you can see a pretty self-contained example


Interesting, I'll look into this, thank you.