简体   繁体   中英

Mock Database connections in haskell

I am trying to write some simple code in haskell where there is a function performs a simple database query. In order to unit test Iam using HUnit but not sure how I can mock the database connection and query response.

Pass the function that performs the database query as a parameter to your code, instead of having it "hardwired". During tests, pass a mock function to the code. In production, pass a function that really performs the database query.

This new function parameter should be at the right level of abstraction. For example, something like

queryDbForClient :: Connection -> SQLString -> ClientId -> IO (Maybe RowData)

is possibly a bad idea, because it still forces the code under test to be aware that things like Connection s and SQL strings exist. Something like this

findClientById :: ClientId -> IO (Maybe Client) 

would likely be better, because then you are free to pass functions that don't use db-specific Connection types at all. They could, for example, be backed by an in-memory reference .

Notice that you can build findClientById out of queryDbForClient by partial application and mapping the result a little. But this should be the task of some setup code, not of the main code that you want to test.


Once you start passing functions in this way for the sake of testability and configurability, some common issues start to appear. For example, what if I have multiple dependencies? Passing them all as positional parameters is a chore. This might lead to passing them together in a record-of-functions, perhaps using Has -like typeclasses so as not to tie your main code to any particular record.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM