Clojure - как правильно смонтировать состояние в модульных тестах - PullRequest
0 голосов
/ 30 августа 2018

Я пытаюсь протестировать некоторые операции с базой данных в приложении luminus с библиотекой базы данных Monger.

В идеале я бы хотел, чтобы сработало следующее. Я удалил часть ненужного кода.

Тестовый файл:

(ns app.test.handler
  (:require [clojure.test :refer :all]
            [app.db.core :as db]))

(testing "create user"
    (db/create-user "test" "test" "test")
    (is (true? true))))

Файл БД

(defstate db*
  :start (-> env :database-url mg/connect-via-uri)
  :stop (-> db* :conn mg/disconnect))

(defstate db
  :start (:db db*))


(defn create-user
  "Creates a new user with a token"
  [username email password]
  (let [user {:username username
              :email email
              :password (hashers/derive password)
              }]
  (mc/insert db "user" user)))

Это не работает и выдает следующую ошибку:

java.lang.ClassCastException: mount.core.DerefableState cannot be cast to com.mongodb.DB

Насколько я могу судить, это неправильно монтирует БД, поэтому она не может вызывать операции с базой данных. Я попытался перенести этот код монтирования в тест, но все равно получил ту же ошибку.

Я заставил это работать:

Тестовый файл

(def db (mg/connect-via-uri "mongodb://127.0.0.1:27017/worldbuilder"))

(testing "create user"
     (let [user {:username "test"
                 :email "test"
                 :password "test"
                 :token "test"
                 }]
    (mc/insert (:db db) "user" user)
    (is (true? true))))

Но для этого необходимо, чтобы я переписал операцию в моем тесте, чтобы победить цель. Если я оставляю соединение выше, но вызываю db / create-user, я получаю ту же ошибку состояния.

Я бы хотел передать это соединение, определенное в моем тестовом файле, в другой файл моей базы данных. Есть ли способ, которым я могу сделать это и заставить его переопределить, как он там установлен?

1 Ответ

0 голосов
/ 13 сентября 2018

Вы должны установить биты состояния в своих тестах, используя clojure.test/use-fixtures, например:

(ns app.test.handler) ; rest of ns block omitted for clarity

(defn start-states [f]
  (mount.core/start)
  (f))

(clojure.test/use-fixtures :once start-states)

Это запустит базу данных до запуска любых тестов.

См. Ссылки, чтобы настроить это: https://clojuredocs.org/clojure.test/use-fixtures

Вот еще немного изящного прочтения о clojure.test (от самого создателя): https://stuartsierra.com/2016/05/19/fixtures-as-caches

...