mercredi 29 août 2018

Clojure - How To Properly Mount State In Unit Tests

I'm attempting to test some database operations in a luminus app with the Monger database library.

Ideally, I'd like the following to work. I've stripped out some of the irrelevant code.

Test File:

(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))))

DB File

(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)))

This doesn't work, and gives me the following error:

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

From what I can tell, this isn't mounting the DB correctly, so it can't call the database operations. I tried to move this mounting code to the test, but still received the same error.

I did get this to work:

Test file

(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))))

But this requires me to re-write the operation in my test defeating the purpose. If I leave the connection above, but call the db/create-user I get the same state error.

I'd like to be able to pass that connection defined in my test file into my other database file. Is there I way I can do this and get it to override how it's being set there?

Aucun commentaire:

Enregistrer un commentaire