发送带有会话数据的模拟响铃请求

Sending a mock ring request with session data

我正在尝试使用 ring.mock.request. But looking at its documentation 对具有 'fake' 会话数据的环形应用程序进行单元测试,但它似乎没有该功能。

在实际应用中,我使用的是 ring.middleware.session 包装器:

(defroutes routes
  (GET "/transactions"  [{session :session}]
    (response (str "Hello " (:username session)))))

(def app
  (wrap-session routes))

在我的测试中:

(app (ring.mock.request/request :get "/transactions"))

但我有点不知道在哪里为我的请求添加这个 'fake' 会话数据(例如类似 (ring.mock.request/request :get "/transactions" :session {:用户名"foo"}).

在该模拟库中没有提供会话数据的选项,因为它取决于服务器部分,而不是请求本身。

当会话中间件处理请求时,它读取表示用密钥签名的会话数据的 cookie。

我们的想法是准备这样一个 cookie 并在请求中传递它。但在这种情况下,您的测试不再是黑盒,因为您使用了一些不应触及且可能会发生变化的内部内容。

一个选项是仅当 运行 测试添加您需要进一步处理的会话数据时才使用特殊处理程序。在您的测试中,您执行两个请求:第一个请求用于该处理程序,第二个请求发送给您的普通处理程序,但传递从第一个请求返回的 cookie。那将是最现实的情况。

另一种选择是在 ring.middleware.session 内部找到一个函数,它可以添加会话数据并对其进行签名以响应。或者用with-redef-fn重新定义其中的一些,几乎是一样的。

看看上面link上的bare-session-request,主要逻辑在那个函数里运行。

您可以为此使用 peridot。重要特征:

peridot is designed to be used with ->, and maintains cookies across requests in the threading.

(-> (peri/session app)
    (peri/request "/session-setter") ;; this would be the route that *sets* the session value
    (peri/request "/transactions"))

其中 /session-setter 是我添加的路由,只是为了在您的会话中设置一个值:

(GET "/session-setter" []
  {:status 200
   :body "OK"
   :session {:username "Roberto"}})

最终你应该得到这样的地图(为简洁起见,我删除了一些键):

{:response {:status 200,
            :headers {...},
            :body "Hello Roberto"},
 :request {...},
 :cookie-jar {"localhost" {"ring-session" {:value "04110b66-1281-4e88-9470-546911e21ca1",
                                           :path "/",
                                           :domain "localhost",
                                           :raw "ring-session=04110b66-1281-4e88-9470-546911e21ca1",
                                           :http-only true}}}}

注意在响应中,我们现在看到 :body "Hello Roberto" 是使用会话密钥 :username 构建的。