Mock Database connections in haskell - 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 Connections 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.

Related

Unit Testing a method which queries the database

So I've created a function which accepts an ID, internally queries a database via a repository from the data returned mutations are made to the data depending on different scenarios and then we return the data.
How would I unit test this function?
Would I stub the find method on my repository layer to return data so I'm not dependant on connecting on the database?
i will argue that you can only unit test code which is unit testable. my definition of unit testable code is code that exhibits these properties:
it gets everything it needs from its inputs
all its work is expressed through return values (or throwing exceptions)
it does not produce any side effects
the code you describe violates #1, by going to the database.
to answer your question directly, you would mock the database call and that mock would provide to your function expected data, such that you can mutate it and compare it to an expected output.
but i think the real right answer is to refactor your code, applying the Single Responsibility Principle. your code under test is doing two things (going to the database and mutating the result), instead of doing just one thing.
i would break out the database portion and assign that as Someone Else's Job. then your code under test could take that database result as an input, and its sole job would be to mutate that data and return the result.
that would, imho, make it unit testable. and when you unit test it, you wouldn't have to mock the db at all, as you could simply write the data you wanted to mutate and supply it the function.

Difference in testing between strongly-typed and weakly-typed languages

I came from JS world and I am used to do thorough testing of all the possible cases that can be a result of weak typing. That way, inside a function I check all the incoming parameters to conform to some criteria.
As an example, in function createUser(username, id, enabled, role){} I would check if username is a string, id is a UUID, status is boolean, and role is a string that must be 'admin', 'user' or 'system'.
I create tests for these cases to make sure that when I pass wrong parameters, tests fail and I need to find bugs that lead to this. At the end, I have quite a lot of tests, many of which are type-checking tests.
Now, I am playing with Swift which is strongly-typed. I use it to create a client app that consumes data from a NodeJS server side. If I want to create a similar createUser() function in Swift, it seems like I need much less tests because type checking is in the language itself.
Is it right to think that a basically a strongly-typed language needs less tests than a weakly-typed one? Some tests just seem to be unnecessary in Swift and the whole test process seems to be more lightweight.
Are there things I can do to write even less tests by using language constructs in some specific manner and still be sure the code is correct and would pass tests by definition?
The use of
optionals and non-optionals, guard, if let
may save you some nil checks
for example -
Guard Statement
A guard statement is used to transfer program control out of a scope if one or more conditions aren’t met.
A guard statement has the following form:
guard condition else {
statements
}
and more generally, read this -
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html

How can I get esqueleto to generate an SQL string for me?

How can I get esqueleto to generate an SQL string from a from statement?
The documentation of toRawSql says that "you may just turn on query logging of persistent". I tried all possible forms of MonadLogger that I could understand, but it never printed any SQL. The same documentation also says "manually using this function ... is possible but tedious". However, no constructors of the type, nor any functions returning values of the type, QueryType are exported. I managed to get around this by noticing that QueryType is a newtype and using unsafeCoerce!
I was also forced to provide a Connection (which I got via SQLite) even though there should be no need to connect to a database to generate the SQL.
This is what I've got. There must be a better way.
withSqliteConn ":memory:" $
\conn -> return $ toRawSql SELECT
(unsafeCoerce ((const mempty)
:: a -> Text.Lazy.Builder.Builder))
(conn, initialIdentState) myFromStatement)
http://hackage.haskell.org/package/esqueleto-1.3.4.2/docs/Database-Esqueleto-Internal-Sql.html
In the time since this question was posted, esqueleto has gone through a number of major revisions. As of version 2.1.2, and several earlier versions, the QueryType a parameter that necessitated your unsafeCoerce has been removed from toRawSql; that major wart is no longer necessary.
As currently implemented, a Connection is required. I believe that, as indicated by the type synonym name, IdentInfo, esqueleto uses this to build identifiers in the query. It may, for example, add the database name. I haven't really plumbed the source in enough depth. Suffice it to say, passing a fake connection (i.e. undefined) doesn't work; I don't know if a mock connection could be implemented. Your solution seems workable.
The rest of your solution should work fine. Since toRawSql is explicitly an internal function, the API here seems reasonable. Although others note that it "should" be possible to generate a connection-neutral string, that appears outside the scope of toRawSql.
You mention that you couldn't use MonadLogger as recommended. What did you try, and what happened?

Snap: Database access with compiled splices

I am trying to get my head around compiled splices. With previouse help I can compile and render some usefull results. I don't fully understand the way it works though.
In interpreted mode, the algorithm is simple: construct root, call handler function given the mapped url, pull data from DB, construct and bind splices out of pulled data, insert them into heist and call the apropriate template.
It is all upside down in compiled mode. I map url directly to cRender and don't call a handler. So I assume all the splice constructing and data processing functions are called at load time.
So my question is when is the database called? Does this happen at load time too?
It is just the sequence of events that I don't understand.
Since splice construction is independent of a particular template rendering, does this mean the splice binding tags are unique accross the whole application?? Are they like global variables?
Thanks
Yes, you are pretty much correct. Although I wouldn't say they are like global variables. They are more like global constants, or a global API. I view compiled splices as an API that your web designer can use to interact with dynamic data.
Compiled splices allow you to insert holes into your markup that get filled with data at runtime. At load time the running monad is HeistT n IO. But at run time the running monad is RuntimeSplice n. So if you're looking at the compiled Heist API, it's very easy to see where the runtime code like database functions need to be: in the RuntimeSplice n monad.

Retrieving pure values from acid state queries

This seems like something that should be easy but how do I get a pure value out of a query if I am using AcidState's Data.Acid.Memory.Pure module. I guess I can generalize the question to "how do I get any value out of the Update monad?". You see, I'm trying to write a test that does the following run-of-the-mill tasks:
Updates a pure AcidState with an object
Queries that Object out of the state using IxSet
Compares the Queried Object and the one returned by the Update for equivalence.
I need a pure "Bool" from this in order to make integration with test frameworks easy. At first I thought I'd simply use runState from Control.Monad.State but I was mistaken (or just didn't do it right). What should I do?
Since you are using Data.Acid.Memory.Pure, you can use the update, query, and update_ functions from that module (instead of the ones from Data.Acid) to look at the result of an event purely. As with regular, impure acid-state, you don't simply "run the Update and Query monads," you have to convert them to an event first. With Data.Acid.Memory.Pure, that means you simply wrap them with the constructors of Event.

Resources