# test-fixture

Test monadic side-effects http://github.com/cjdev/test-fixture#readme

LTS Haskell 9.13: | 0.5.1.0 |

Stackage Nightly 2017-11-18: | 0.5.1.0 |

Latest on Hackage: | 0.5.1.0 |

**Joe Vargas**

**jvargas@cj.com**

#### Module documentation for 0.5.1.0

- Control
- Control.Monad

# test-fixture

The test-fixture package is a Haskell library that makes it possible to easily write deterministic unit tests for code that encapsulates effects into monadic typeclasses. For example, given some typeclasses used to encapsulate effects:

```
class Monad m => MonadDB m where
fetchRecord :: DBRecord a => Id a -> m (Either DBError a)
insertRecord :: DBRecord a => a -> m (Either DBError (Id a))
class Monad m => MonadHTTP m where
sendRequest :: HTTPRequest -> m (Either HTTPError HTTPResponse)
```

One can write `IO`

instances to run the actual code in a real environment:

```
instance MonadDB IO where
fetchRecord = Postgres.fetchRecord
insertRecord = Postgres.insertRecord
instance MonadHTTP IO where
sendRequest = sendRequestIO
```

Then use those typeclasses to implement some sort of side-effectful function:

```
sendAndFetch :: (MonadDB m, MonadHTTP m, DBRecord a)
=> HTTPRequest -> m (Either AppError a)
sendAndFetch = ...
```

Testing this function might be difficult because of all the different possible combinations of scenarios that must be considered. Creating lots of different monads and instances for each case can be boilerplate-heavy and tedious. Using test-fixture, the boilerplate is unnecessary:

```
mkFixture "Fixture" [ts| MonadDB, MonadHTTP |]
spec = describe "sendAndFetch" $ do
it "returns a record when the http request and db fetch are successful" $ do
let (fixture :: Monad m => Fixture m) = def
{ _fetchRecord = \_ -> return $ Right procureRecord
, _sendRequest = \_ -> return $ Right responseOk
}
let result = unTestFixture (sendAndFetch simpleRequest) fixture
result `shouldBe` Right (User "someone@example.com")
it "returns an error when the http request is not successful" $ do
let (fixture :: Monad m => Fixture m) = def
{ _fetchRecord = \_ -> return $ Right procureRecord
, _sendRequest = \_ -> return $ Left errorNotAuthorized
}
let result = unTestFixture (sendAndFetch simpleRequest) fixture
result `shouldBe` Left (AppHTTPError errorNotAuthorized)
```

For more information and a more complete explanation, see the documentation on Hackage.

## Changes

# 0.5.1.0 (October 30, 2017)

Added lifting instances for

`MonadIO`

,`MonadThrow`

,`MonadCatch`

, and`MonadMask`

to`TestFixtureT`

.

# 0.5.0.2 (July 27, 2017)

Added support for

`template-haskell-2.12.0.0`

and GHC 8.2.1.

# 0.5.0.1 (June 2, 2017)

Fixed an issue where using

`mkFixture`

with a typeclass that used the`DefaultSignatures`

extension caused an internal error (#30).

# 0.5.0.0 (November 28, 2016)

**Breaking**:`mkFixture`

now supports constraints in the same form as a Haskell`deriving`

clause, which permits “partially-applied” constraints. A new`ts`

quasiquoter is provided for the purpose of writing a comma-separated list of Haskell types; see the documentation for more details (#25).- Generating fixtures that do not derive any typeclasses no longer produces an error (#28).

# 0.4.2.0 (November 14, 2016)

- Attempting to generate a fixture for a multi-parameter typeclass now produces a better error message (#24).
- Fixtures can now be generated for typeclasses containing infix operators as methods. They will be prefixed with a tilde (
`~`

) instead of an underscore (#26).