Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

188
Visualizações
Nested transactions using savepoints for tests in clojure.jdbc and postgres

In my unit tests, I have a fixture that creates a rollback transaction in order to clean up the database after my tests have run. It looks something like this:

(defn with-rollback [test-fn]
  (let [db-conn    (db/connect db/test-pg-db)]
    (jdbc/with-db-transaction [txn db-conn {:isolation :serializable}]
      (jdbc/db-set-rollback-only! txn)
      (-> (mount/only [#'db/db])
          (mount/swap {#'db/db txn})
          (mount/start))
      (test-fn)
      (mount/stop))
    (db/disconnect db-conn)))

Then in the tests I do (use-fixtures :each fixtures/with-rollback).

This works great, except in tests where I want to test that error conditions actually rolls back transactions. For example I want to test that when a request to an external service fails I don't write anything to the db.

Is there any way to get behaviour similar to nested transactions for my use case? I had an idea to override the jdbc/db-transaction* function with something that creates savepoints when a transaction is opened and rolls back to the nearest one when an exception is caught - but I could never get it to work. Appriciate any help!

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

I was struggling with this problem as well and ultimately decided to go with a workaround of having separate files for "normal" tests and transaction tests. This way it is possible to use separate fixtures.

So you would use a rollback fixture for the normal tests and a clear/truncate fixture for the transaction tests. Truncating has a bigger performance cost, hence the fixture should be used sparingly.

Here is the truncate fixture implementation. It is assumed that the used schema is public and that there are some data stored about database migrations in a schema_migrations table that should be left intact.

(defn truncate-db [tests]
  (tests)
  (jdbc/execute! db-conn
                 "DO $$ BEGIN
                    EXECUTE 'TRUNCATE TABLE '
                    || (SELECT string_agg(table_name::text, ',')
                        FROM information_schema.tables
                        WHERE table_schema = 'public'
                        AND table_type = 'BASE TABLE'
                        AND table_name != 'schema_migrations')
                    || ' CASCADE';
                  END; $$;"))
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda