Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duct tests with integrant #60

Open
zerg000000 opened this issue Jul 13, 2017 · 3 comments
Open

Duct tests with integrant #60

zerg000000 opened this issue Jul 13, 2017 · 3 comments

Comments

@zerg000000
Copy link

zerg000000 commented Jul 13, 2017

The Duct unit test example only cover init a handler with no dependences which is impossible in real world. Currently, if I want to do integration test with db. I need to do something like

(defn config-fixture [keys deps]
  (fn [f]
    (let [config (-> (duct/read-config (io/resource "test.edn"))
                     duct/prep
                     (dissoc :duct.core/handler))] ; remove handler because it will start the jetty
      (let [sys (ig/init config keys)]
        (ig/run! sys keys (fn [_ db]
                            (reset! deps db)
                            (f)
                            (reset! deps nil)
                            (ig/halt! sys keys)))))))

(def system (atom nil)) ; this is the trick to use ig dependents

(use-fixtures :once (fixtures/config-fixture
                      [:duct.database/sql]
                      system))

(deftest db-itest
    (testing "create dumb in db"
        (let [dumbs (-> (s/gen :dumb/dumb)
                        (gen/sample 100))
              db-spec @system
              apply-dissoc #(apply dissoc %1 %2)]
            (is db-spec "db-spec should exists")
            (doseq [dumb dumbs]
                (let [expected dumb
                       actual (db/create db-spec dumb)]
                    (is (= expected actual) "inserted dumb should be same as input"))))))

is there any better method to test with integrant?

The primary use case is for testing all the boundaries in duct, to see if they are healthy.

@weavejester
Copy link
Collaborator

Ideally in Duct you'll have three types of tests:

  • System tests that init the entire system and test it from end to end
  • Integration tests that test the boundaries against the database
  • Unit tests that use mocks or stubs of the boundary protocols

So my initial advice is to test the boundary functions directly:

(deftest db-test
  (jdbc/with-db-transaction [tx db-spec]
    (jdbc/db-set-rollback-only! tx)
    (seed-database tx)
    (let [db (->Boundary tx)]
      ...)))

If you want to test boundary functions in conjunction with your handler, perhaps because you're uncertain of the interactions between the handler and the database, then you could use init-key directly:

(deftest db-test
  (jdbc/with-db-transaction [tx db-spec]
    (jdbc/db-set-rollback-only! tx)
    (seed-database tx)
    (let [db (->Boundary tx)
          handler (init-key :foo.handler/bar {:db db})]
      ...)))

Obviously you can wrap a lot of the above in a macro or function to automate the process of setting up the transaction and seeding the database.

@zerg000000
Copy link
Author

I would consider my tests falling into second case, that's why we will have code that's only pick the keys needed. As the example you provided, seed-database would be some calls to ragtime, since the ragtime configuration is a bit duct-ized in config.edn, if we don't touch the integrant for migrator.ragtime we needs to add some code that's similar to migrator.ragtime to seed the database.

@weavejester
Copy link
Collaborator

That makes sense. In which case, rather than using init-key, you can use a selective init.

(deftest db-test
  (jdbc/with-db-transaction [tx db-spec]
    (jdbc/db-set-rollback-only! tx)
    (let [config  (assoc test-config :duct.database/sql {:connection tx})
          system  (-> config duct/prep (ig/init [:foo.handler/bar]))
          handler (:foo.handler/bar system)]
      ...)))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants