Тестирование с core.async - сбросить блоки внутри теста?
Я пытаюсь написать такой тест:
(deftest login-form-rendering
(async done (with-redefs [http/post fake-login-success]
(with-mounted-component (c/login-form login!)
(fn [c div]
(.click (.getElementById js/document "Login"))
(is (= (:page @app-state) :location)))))
(done)))
У меня есть этот макет:
(defn fake-login-success [& _]
(let [ch (chan)
response {:status 200}]
(go (>! ch response)
ch)))
Функция входа в систему делает это:
(defn login! [username password]
(go (let [result (->> {:form-params {:username @username :password @password}}
(http/post "/api/login")
(<!))
{status :status body :body} result]
(case status
401 (swap! app-state assoc :page :bad-login)
200 (swap! app-state assoc :page :location)))))
Форма входа - это компонент реагента, который принимает обратный вызов для onClick. app-state является глобально доступным атомом.
Проблема, с которой я сталкиваюсь, состоит в том, что блок go внутри входа в систему! никогда не выполняется. Есть ли что-то, что мне нужно сделать, чтобы очистить канал или что-то?
Я вижу, что есть также этот вопрос без ответа, который похож: Тестирование кода core.async в ClojureScript. Кажется, одно отличие состоит в том, что у меня нет явного канала в тестируемом коде. Это генерируется постом cljs-http.
1 ответ
Я считаю, что ваша проблема - неуместная скобка.
(let [ch (chan)
response {:status 200}]
(go (>! ch response)
ch))
Возвращаемое значение этого let
это go
канал блока. Это канал, который ничего не содержит, так как:
go
Блок пытается установить небуферизованный канал, требуя, чтобы какая-то другая операция "встретила" его и сделала дополнительный дубль для продолжения его собственного выполнения.ch
он лексически скрыт от внешнего мира, поэтому не может существовать ни одной операции, которая могла бы выполнить дополнительный дубль.
Если что-то что-то взяло (или мы добавили буфер в ch
так что первый путь успешен), ch
будет помещен на возвращенный канал.
(let [ch (chan)
response {:status 200}]
(go (>! ch response))
ch)
Возвращаемое значение этого let
является ch
, без дополнительного канала, оборачивающего это. go
блок припаркован, пытаясь надеть ch
пока что-то вроде вашего теста не дойдет до того, чтобы забрать его.
Тем не менее, поскольку мы в конечном итоге просто хотим построить канал с константой, go
Само по себе кажется самым простым решением:
(defn fake-login-success [& _]
(go {:status 200})