如何测试 Scotty 端点

问题描述

使用以下 Scotty 端点:

myendpoint :: Text -> ScottyM ()
myendpoint info =
    post "/foo/bar/:var" $ do
        var :: Text <- param "var"
        query :: Query <- jsonData
        result <- liftIO $ retrieveResult info var query
        json $ result

runApi :: IO ()
runApi = scotty 4602 $ do
    myendpoint

例如如何使用不同的可能输入测试 myendpoint

info1 = "foo"
query1 = Query { qParam1 = "foo",qParam2 = "bar" }
var1 = "bar"
expect1 = Result { foo = "foo",bar = "bar" }

res1 = decode $ test_myendpoint info1 query1 var1
res1 `shouldBe` expect1

info2 = "baz"
query2 = Query { qParam1 = "hello",qParam2 = "there" }
var2 = "boo"
expect2 = Result { foo = "biz",bar = "dev" }

res2 = decode $ test_myendpoint info2 query2 var2
res2 `shouldBe` expect2

我很想简单地在另一个线程中运行 API,然后使用一些 JSON 查询端点的真实性,但是有没有更简洁的方法来做到这一点? (虽然上面的好处是真正的端到端测试)

解决方法

找到答案了。需要导入 hspec-waihspec-wai-json

然后我们不是直接运行 api,而是创建一个返回 apiIO Application 函数,然后是另一个实际运行该事物的 runApi 函数。

import           Network.Wai                 (Application)
import           Network.Wai.Handler.Warp    (run)

api :: IO Application
api = scottyApp $ do
    myendpoint

runApi :: IO ()
runApi =
    api >>= run 460

现在我们可以在测试中自由使用 with api

import           Test.Hspec
import           Test.Hspec.Wai      as W
import           Test.Hspec.Wai.JSON

spec :: Spec
spec = with api $ do
    describe "testing some endpoint" $ do
        it "should return correct data" $ do
            get "/foo/bar/whatever" `shouldRespondWith`
                [json|{foo: "foo",bar: "bar"}|]