Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

189
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda