Аннотированные тесты Spring и JUnit: создание фиксаторов в отдельных транзакциях - PullRequest
3 голосов
/ 26 мая 2010

Я тестирую свои DAO в Hibernate с помощью Spring и JUnit.

Я бы хотел, чтобы каждый метод тестирования начинался с предварительно заполненной БД, т.е. объекты Java были сохранены в БД в транзакции Hibernate, которая уже была зафиксирована. Как я могу это сделать?

При использовании @After и @Before методы выполняются в той же транзакции Hibernate, что и методы, оформленные с помощью @Test и @Transactional (кэш первого уровня может не очищаться к моменту запуска реального метода тестирования). @BeforeTransaction и @AfterTransaction, очевидно, не могут работать с Hibernate, потому что они не создают транзакции, даже если метод аннотирован @Transactional в дополнение к @ Before / AfterTransaction.

Есть предложения?

Ответы [ 2 ]

5 голосов
/ 26 мая 2010

Одним из способов может быть вывод вашей логики инициализации на внешний сервис с помощью транзакционных методов, которые выполняются из аннотированных методов @BeforeTransaction и @AfterTransaction в тестовом классе.

Еще одним преимуществом этого подхода является возможность многократного использования кода инициализации в тестах.

Например, вы можете использовать SpringJunit4ClassRunner, как описано здесь , например:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"testContext.xml","services.xml"})
public class MyServiceTest {

    @Autowired    
    private TestDataService testDataService;

    @Before
    public void setUp(){
        testDataService.addTestData();
    }

    @Test
    public void testSomething() throws Exception {
         // ...
    }
}


public interface TestDataService {

    void addTestData();

}

public class TestDataServiceImpl implements TestDataService {

    @Transactional
    public void addTestData(){
        // TODO
    }

}

Это то, что мы делаем в наших проектах на базе Spring.

Убедитесь, что транзакционная конфигурация правильная. Если вы хотите избежать разделения класс / интерфейс, установите для элемента proxy-target-class значение true в элементе.

2 голосов
/ 26 мая 2010

dbUnit является хорошей основой для работы.

Короче говоря, он должен быть запущен методом setUp(), и он удаляет все содержимое из указанных таблиц, а затем заполняет их содержимым из файла XML.

В противном случае вы можете попытаться выполнить метод setUp() в новой транзакции, например:

@Before
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void setUp() {
    // initial logic .. 
}
...