Rewriting to Haskell–Testing
Rewriting to Haskell (Series)
Rewriting to Haskell–Intro Rewriting to Haskell–Project Setup Rewriting to Haskell–Deployment Rewriting to Haskell–Automatic Formatting Rewriting to Haskell–Configuration Rewriting to Haskell–Standing on the shoulders of Rails Rewriting to Haskell–Making GHC More Nitpicky Rewriting to Haskell–Testing Rewriting to Haskell–Linting Rewriting to Haskell–Parsing Query Params Rewriting to Haskell–Parsing Query Params, Again Rewriting to Haskell–ErrorsWe have managed to delay testing by leaning on Ruby RSpec for a while. It’s time to do the right thing and write some tests in Haskell.
We peaked at the “How To Test Servant Applications” cookbook page and decided to go the hspec-wai
way. In fact, using servant-client
seemed a bit too involved and coupled with Servant. The former, on the other hand, enables us to test any wai application.
With that in mind we created a test/Spec.hs
:
main :: IO ()
= do
main "DATABASE" "stream_test"
setEnv -- ^ See https://odone.io/posts/2020-03-23-rewriting-haskell-configuration.html for the why.
<- configuredApp
application <- getConnection
connection $ spec application connection
hspec
spec :: Application -> Connection -> Spec
= with (pure application) $ after_ (truncateTables connection)
spec application connection -- ^ After each spec item truncate tables.
$ describe "GET /servant/search"
$ do
"with no query it returns all posts ordered by descending creation date" $ do
it <- liftIO . createUser $ connection
user <- liftIO randomUTCTime
now let later = addUTCTime 1 now
let olderPostAttributes =
defaultPostAttributes= userId user,
{ postAttributesUserId = Just now
postAttributesCreatedAt
}let newerPostAttributes = olderPostAttributes {postAttributesCreatedAt = Just later}
<- liftIO $ createPost connection olderPostAttributes
olderPost <- liftIO $ createPost connection newerPostAttributes
newerPost "/servant/search"
get `shouldRespondWith` [json|
-- ^ Using hspec-wai-json and some Template Haskell to generate JSON.
{ users: [#{user}],
-- ^ Behind the curtains aeson-qq is used. Thus, you can interpolate variables:
-- https://github.com/sol/aeson-qq#aeson-qq-json-quasiquoter-for-haskell
attachments: [],
comments: [],
posts: [#{newerPost}, #{olderPost}]
}
|]
-- ...
At the moment we are just testing through the endpoints as shown above. Stream is a simple application so we feel confident with this approach. Should the need for other types of tests arise, then HSpec will have our backs.