1

I want to unit-test a function that returns a complex nested data structure, but I'm only interested in certain fields of that structure. For example:

expectedResult = Right (
  UserRecord {
    name = "someName",
    id = <don't care>
    address = AddressRecord {
      street = "someStreet",
      id = <don't care> 
      }
    }
  )

Is there a generic way to assert a result of the above form in HSpec? That is, some way to write an expression

result `shouldBe` expectedResult

where I do not need to specify those parts of the expected result that I am not interested in? I found this answer, which requires to copy over all don't care fields from result to expectedResult; this might get rather tedious. Maybe there is a standard approach using lenses? Or some library with assertion helpers I haven't heard of?

Ulrich Schuster
  • 1,670
  • 15
  • 24
  • Is it a coincidence that you 'don't care' about the `id` fields? I'm asking because this is typical test smell I often encounter in general (i.e. in OOP contexts as well). IDs are often generated by a database, which make them non-deterministic and thus more difficult to test. Database-generated IDs in general has other architectural downsides, so if this is the case, it may be worthwhile to consider a better (and more functional) design. – Mark Seemann May 03 '21 at 05:29
  • In mz particular case at hand, it's not about the ID field in particular (I would use UUIDs if the DBMS permits). I'm trying to test a Servant server, where HTTP responses have all sorts of automatically fields I don't care about in the test (host name, server name and version, etc.) – Ulrich Schuster May 03 '21 at 06:11

1 Answers1

4

A simple approach:

result `shouldSatisfy` \a ->
    name a == "someName"  &&
    street (address a) == "someStreet"
Ari Fordsham
  • 2,437
  • 7
  • 28