2015-10-05 64 views
0

我有一個單元測試的應用程序。在此測試中,我創建了一個用戶 帳戶,然後對其進行測試。然後我修改它並測試修改後的 版本。問題是,它似乎在做一些亂糟糟的事情。 Am 我錯了嗎?無論哪種方式,我該如何解決?Clojure測試運行不正常?

在我看來,當我運行測試,然後修改數據庫中的測試

在此版本後,它works--沒有錯誤:

(ns myapp.db.account-test 
    (:use expectations) 
    (:require 
    [myapp.db   :as DB] 
    [myapp.db.account :as Account] 
    )) 

(defn- $reset-database 
    "Reset the database to a pristine state." 
    [] 
    (DB/create-db)) 

($reset-database) 
(let [acct-1 {:email "[email protected]" :username "user-one" :password "goodpwd1"} 
     acct-2 {:email "[email protected]" :username "user-two" :password "goodpwd2"}] 
    (Account/create acct-1) 
    (let [db-acct (Account/seek {:email (:email acct-1)})] 
    (expect (:email acct-1) (:email db-acct)) 
    (expect (:username acct-1) (:username db-acct)) 

    (expect true (Account/authenticate {:email (:email acct-1) :password "goodpwd1"})) 
    (expect false (Account/authenticate {:email (:email acct-1) :password "badpwd"})) 

    ;; Now try to change some attributes of the account 
    #_(Account/modify acct-1 acct-2) 
) 

然後...

myapp 10:28 PM ~/Projects/myapp/myapp.net/code/myapp $ lein test myapp.db.account-testPicked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar 
Rewriting src/cljx to target/generated/clj (clj) with features #{clj} and 0 transformations. 
Rewriting src/cljx to target/generated/cljs (cljs) with features #{cljs} and 1 transformations. 
Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar 

lein test myapp.db.account-test 

Ran 0 tests containing 0 assertions. 
0 failures, 0 errors. 

Ran 4 tests containing 4 assertions in 171 msecs 
0 failures, 0 errors. 

但是,如果我取消註釋最後一行,則'以前'測試失敗。

... 
    ;; Now try to change some attributes of the account 
    (Account/modify acct-1 acct-2) 
) 

然後...

myapp 10:40 PM ~/Projects/myapp/myapp.net/code/myapp $ lein test myapp.db.account-testPicked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar 
Rewriting src/cljx to target/generated/clj (clj) with features #{clj} and 0 transformations. 
Rewriting src/cljx to target/generated/cljs (cljs) with features #{cljs} and 1 transformations. 
Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar 

lein test myapp.db.account-test 

Ran 0 tests containing 0 assertions. 
0 failures, 0 errors. 

failure in (account_test.clj:21) : myapp.db.account-test 
(expect 
true 
(Account/authenticate {:email (:email acct-1), :password "goodpwd1"})) 

    act-msg: exception in actual: (Account/authenticate {:email (:email acct-1), :password "goodpwd1"}) 
    threw: class java.lang.NullPointerException - 
      com.lambdaworks.crypto.SCryptUtil$check (SCryptUtil.java:74) 
      on (core.clj:41) 
      on (account.clj:109) 
      on (account_test.clj:21) 

failure in (account_test.clj:22) : myapp.db.account-test 
(expect 
false 
(Account/authenticate {:email (:email acct-1), :password "badpwd"})) 

    act-msg: exception in actual: (Account/authenticate {:email (:email acct-1), :password "badpwd"}) 
    threw: class java.lang.NullPointerException - 
      com.lambdaworks.crypto.SCryptUtil$check (SCryptUtil.java:74) 
      on (core.clj:41) 
      on (account.clj:109) 
      on (account_test.clj:22) 

Ran 4 tests containing 4 assertions in 234 msecs 
0 failures, 2 errors. 

在如此重要的情況下,myapp.db.account的相關部分是:

(defn seek 
    "Get an account by email address" 
    [{:keys [email]}] 
    (row-to-hash (get-account-by-email {:email email}))) 

(defn modify 
    "Modify an account." 
    [{current-email :email} 
    {new-email  :email new-username :username new-password :password}] 

    (jdbc/with-db-transaction [connection db-env/spec] 
    (let [current (seek {:email current-email})] 

     (update-email-by-email! {:current_email current-email :new_email new-email})))) 

(defn authenticate 
    "Try to authenticate given an identifier and a password. 
    Note that this returns a false case in the case of actual falsity, but nil 
    in the case of a poorly formed query (such as missing credentials)" 
    [{:keys [id email username password]}] 
    (and 
    password 
    (scrypt/verify 
     ;; compare this password attempt 
     password 
     ;; with this hash from the db (when possible) 
     (:passhash 
     (first 
      (cond 
      ;; Branch on which field is present. 
      id  (get-authorization-fields-by-id  {:id id}) 
      email (get-authorization-fields-by-email {:email email}) 
      username (get-authorization-fields-by-username {:username username}) 
      ;; Default to false 
      :else nil)))))) 

回答

1

你不應該運行lein test,你應該使用lein expectations(它需要您的project.clj中有一個插件):

:plugins [[lein-expectations "0.0.7"]] 

expectations在jvm關閉時被調用。我的猜測是,lein test正在編譯你的文件,它評估你的數據庫修改,以及之後的預期。直到你介紹了你希望在之後運行的改變爲止。

要解決此問題,請在您的期望中包含要運行的代碼。以下是使用上面的代碼的示例。它使用期望庫中的'more->宏。

(let [acct-1 {:email "[email protected]" :username "user-one" :password "goodpwd1"} 
     acct-2 {:email "[email protected]" :username "user-two" :password "goodpwd2"}] 

    (expect 
    (more-> 
     true (do ($reset-database) 
       (Account/create acct-1) 
       (Account/authenticate {:email (:email acct-1) :password "goodpwd1"})) 
     false (do ($reset-database) 
       (Account/create acct-1) 
       (Account/authenticate {:email (:email acct-1) :password "badpwd"}))))) 
+0

我切換到'$> lein expectations myapp.db.account-test'(遵循'expected'網站上的指示),但我看到完全相同的行爲。 –

+0

嘗試在你的期望值內進行修改(例如'(expect true(do(修改...)(依賴於修改的東西)))'否則所有在編譯時評估的代碼將在預期之前運行。 –

+0

謝謝,我也在沿着這條路走下去,事實證明這是正確的答案(至少對我而言),我會修改你的答案以包含工作解決方案的例子。 –