Spring / JUnit тесты - обработка нескольких транзакций за тест - PullRequest
0 голосов
/ 08 мая 2019

Я новичок в Spring Boot Testing и не уверен, правильно ли мы его используем. Мы используем Spring Boot 1.5.8.RELEASE, включая JUnit 4.12. Во время тестов похоже, что мы делаем ручную обработку транзакций. Я нашел следующий код:

@Service
public class DatabaseSessionManager {

    @PersistenceUnit
    private EntityManagerFactory entityManagerFactory;

    public void bindSession() {
        if (!TransactionSynchronizationManager.hasResource(entityManagerFactory)) {
            EntityManager entityManager = entityManagerFactory.createEntityManager();
            TransactionSynchronizationManager.bindResource(entityManagerFactory, new EntityManagerHolder(entityManager));
        }
    }

    public void unbindSession() {
        EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager
            .unbindResource(entityManagerFactory);
        EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
    }

    public void begin() {
        if (!EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory).getTransaction().isActive()) {
            EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory).getTransaction().begin();
        }
    }

    public void commit() {
        if (EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory).getTransaction().isActive()) {
            EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory).getTransaction().commit();
        }
    }
}

В нашем тестовом суперклассе в качестве примера используется следующий метод @Before:

    @Before
    public void setup() throws Exception {
        sessionManager.unbindSession();
        sessionManager.bindSession();
        MockSecurityContext();
//      databaseChecker.clearRepositories(getEntityClass());
        truncateDatabaseService.truncate();

        ValidationInfo validationInfo = mapper.readValue(getValidationFile(), ValidationInfo.class);
        dummyObject1 = (T) objectBuilder.buildValidObject(validationInfo, "TG");
        dummyObject2 = (T) objectBuilder.buildValidObject(validationInfo, "ZH");
        patchObject = (T) objectBuilder.buildValidObject(validationInfo, "SG");
        patchObject.setId(null);
        patchObject.setKanton(null);
        sessionManager.commit();
        sessionManager.begin();
    }

* во время buildValidObject () некоторые связанные дочерние объекты сохраняются.

Теперь я должен провести некоторый рефакторинг, и я не могу поверить, что нет лучших решений. Другие, работающие над проектом, сказали, что мы должны совершить транзакцию для имитации поведения в реальном мире. Мы очищаем базу данных после каждого теста с помощью @After. Каждая таблица ... это замедляет массивный тест. Я ищу лучшие решения.

Я думаю, что невозможно выполнить откат нескольких транзакций с @Before, @Test и @After, когда они совершены?

Или как мы можем сохранить данные перед каждым тестом, а затем начать новую транзакцию для теста И сохранить базу данных чистой?

...