Fork me on GitHub
#testing
<
2022-08-14
>
Alejandro17:08:03

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: https://www.youtube.com/watch?v=D37dc9EoFus

mauricio.szabo19:08:00

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...

Alejandro19:08:43

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

mauricio.szabo19:08:58

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))

mauricio.szabo19:08:17

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

mauricio.szabo20:08:01

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

mauricio.szabo20:08:25

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

mauricio.szabo20:08:08

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

Alejandro20:08:17

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

Alejandro20:08:34

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: https://zendesk.engineering/auditspec-testing-side-effects-in-functional-code-ec4c63f8d0c6

vemv21:08:20

@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 https://github.com/seancorfield/next-jdbc/pull/209

Alejandro18:08:11

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