我正在用Spring和JUnit测试我的Hibernate DAO。
我希望每个测试方法都以预先填充的DB开始,即Java对象已经保存在数据库中,已经提交了一个Hibernate事务。我怎么能这样做?
使用@After和@Before,方法在与@Test和@Transactional装饰的方法相同的Hibernate事务中执行(在实际测试方法启动时,第一级缓存可能不会刷新)。 @BeforeTransaction和@AfterTransaction显然不能与Hibernate一起使用,因为除了@ Before / AfterTransaction之外,即使该方法使用@Transactional注释,它们也不会创建事务。
有什么建议吗?
答案 0 :(得分:5)
一种方法是使用事务方法将您的初始化逻辑外部化到外部服务,这些方法是从测试类中的@BeforeTransaction和@AfterTransaction注释方法执行的。
这种方法的另一个好处是可以跨测试重用初始化代码。
例如,您可以使用像here这样的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的项目中所做的事情。
确保transactional configuration正确无误。如果要避免类/接口分离,请在元素中将proxy-target-class设置为true。
答案 1 :(得分:2)
dbUnit是一个很好的工作框架。
简而言之,它应该从setUp()
方法开始,它会从指定的表中删除所有内容,然后用XML文件中的内容填充它们。
否则,您可以尝试在新事务中执行setUp()
方法,如下所示:
@Before
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void setUp() {
// initial logic ..
}