Unit Testing - Haskell

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Martins

Hello guys!

Could you, please, share your thoughts how you would go about unit testing the following code.
It has interpreters for making http GET and POST requests. The implementation has internal state,
that stores cookies between requests, as well as adds a constant user agent string to all requests.

https://gist.github.com/martinserts/d206b7778f3a4f4782dcf16077d4b794

I would like to test at least the following scenarios:

  1. Requests are delegated to Network.HTTP.Req.
  2. Cookies are retained between multiple requests.
  3. Outgoing requests contain our custom user agent string

In Scala, I would use a mocking framework such as mockito, and verify outgoing calls.
In Haskell it's probably much different.

May be you could share some Haskell projects with exemplary unit testing that I could learn from?

GitHub Gist: instantly share code, notes, and snippets.
Torsten Schmits

you're using in-other-words!!! :scream:

Torsten Schmits

I see two ways how I would do it:

  1. use an internal effect abstracting R.Option -> m response, then use a pure interpreter in your test
  2. spin up a servant in a bracket in your test
Martins

Torsten Schmits said:

I see two ways how I would do it:

  1. use an internal effect abstracting R.Option -> m response, then use a pure interpreter in your test
  2. spin up a servant in a bracket in your test

Great ideas! I will contemplate them!

Torsten Schmits

FYI I'm doing method 2. in my tests for the Polysemy variant of your issue: https://github.com/tek/polysemy-http/blob/master/packages/polysemy-http/integration/Polysemy/Http/Server.hs

polysemy effect for http-client. Contribute to tek/polysemy-http development by creating an account on GitHub.
Martins

Wow such a complete solution!

Torsten Schmits

have fun! :sweat_smile:

Love Waern (King of the Homeless)

Nice to see someone try out in-other-words! How's your experience with it been so far?
Small optimization, by the way: since you're using Embed IO in httpClientToIO, you could use fmap snd . stateToIOSimple instead of evalState. That way, you can also get rid of the StateThreads threading constraint.

Martins

Thanks for the tip and a great library. I am not an advanced Haskell programmer, so this
stuff is actually over my head :) But that does not discourage me, since in-other-words has really good
documentation. I read and reread it several times, and each time understand something a tiny bit better.
I see how much effort you have put in!

Love Waern (King of the Homeless)

That's encouraging to hear! I knew in-other-words is at the very top end of the scale when it comes to effect system complexity, so I poured everything I had into documenting it.
Fortunately, I think most of the REALLY complicated stuff will only rarely be relevant for the end user, and the basics of the library are still fairly simple. It helps that it's pretty similar to polysemy and fused-effects.

Torsten Schmits

amazing. I started the same way with polysemy and there was almost no documentation around :sweat_smile: