sqlitehaskellyesod-test

Haskell: Using in-memory sqlite db in Yesod Tests?


I'm trying to make my first Yesod website, and was now adding tests.

I'm setting up like this:

shortblitoWebServerSpec :: ShortblitoWebServerSpec -> Spec
shortblitoWebServerSpec =
  yesodSpecWithSiteGenerator $
    runNoLoggingT $
      withSqlitePool ":memory:" 1 $ \pool -> do
        let app =
              App
                { appLogLevel = LevelWarn,
                  appStatic = shortblitoWebServerStatic,
                  appConnectionPool = pool,
                  appGoogleAnalyticsTracking = Nothing,
                  appGoogleSearchConsoleVerification = Nothing
                }
        _ <- runSqlPool (runMigrationQuiet migrateTables) pool
        pure app

And have some tests:

spec :: Spec
spec = shortblitoWebServerSpec $
  ydescribe "ShortenerR" $ do
    yit "Home page exists" $ do
      get ShortenerR
      statusIs 200
    yit "Post to shorten" $ do
      postBody ShortenerR "test"
      statusIs 200

When I run that I get the following error:

11/Jun/2021:14:52:15 +0200 [Error#yesod-core] SQLite3 returned ErrorError while attempting to perform prepare "SELECT \"id\",\"long\" FROM \"url\" WHERE \"long\"=?": no such table: url @(yesod-core-1.6.18-Ab7hNtiUzJgGsCLpKcpJyh:Yesod.Core.Class.Yesod src/Yesod/Core/Class/Yesod.hs:688:5)

However, when I change the :memory: to test.db the tests run fine.

So somewhere the in-memory db gets lost. But I'm not sure how to prevent that.

How do I solve this? So I can use an in-memory db for testing?

Thanks!


Solution

  • The documentation of withSqlitePool mentions:

    Like createSqlitePool, this should not be used with :memory:.

    The documentation of createSqlitePool mentions:

    Note that this should not be used with the :memory: connection string, as the pool will regularly remove connections, destroying your database. Instead, use withSqliteConn.

    I don't know enough about Yesod and your exact use case to give more help.