我有集成测试(在Jetty下运行),我打开页面(通过使用Selenium)并检查有关此活动的记录是否已添加到数据库(HSQL)。但它不起作用 - JPA(Hiberante)添加记录(我在日志中看到它)但是当我执行SELECT查询时根本没有记录。
测试用例:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:spring/DispatcherServletContext.xml"
})
@TransactionConfiguration(defaultRollback = false)
public class WhenUserOpenNotExistingPage
extends WhenUserAtAnyPage<NotFoundErrorPage> {
private final String currentUrl;
@Autowired
private SuspiciousActivityDao suspiciousActivities;
private String generateRandomUrl() {
return String.format(
"/tests/page-does-not-exists-%s.htm",
RandomStringUtils.randomNumeric(5)
);
}
public WhenUserOpenNotExistingPage() {
currentUrl = generateRandomUrl();
page.open(currentUrl);
}
@Test
@Transactional(readOnly = true)
public void incidentShouldBeLoggedToDatabase() {
SuspiciousActivity activity =
suspiciousActivities.findByPage(currentUrl);
assertNotNull(activity);
}
}
同样WhenUserOpenNotExistingPage()
(构造函数)调用两次(我不知道它为什么会发生,可能是我问题的根源)。
答案 0 :(得分:1)
我假设您在测试用例中向数据库添加了一些内容,并且您在Jetty上运行的应用程序正在使用相同的数据库。如果您的数据库使用上面的任何隔离级别读取uncommited,则在该测试用例完成之前,您在测试用例中所做的更改将不可见。这是因为您的数据库代码加入了测试开始时创建的事务。
默认情况下,此测试事务在测试完成后回滚,因此更改在当前测试(事务)中可见,但在外部(通过不同的线程/连接)不可见并且回滚。您正在使用defaultRollback = false
属性更改默认行为,但这仅表示您在一个测试中所做的更改不会被Web应用程序(不同的数据库连接)看到,但会在后续测试中显示(在提交后) )。不太有用。
你几乎没有选择:
通过将@TransactionConfiguration
替换为:
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class})
这将覆盖默认的测试执行侦听器,从堆栈中删除TransactionalTestExecutionListener
您可以从不同的主题或传播REQUIRES_NEW
最后,您应该考虑在JUnit之外进行设置。也许你可以从应用程序本身进行设置?
对于构造函数 - 每个测试都会创建一个新的JUnit测试类实例。 JUnit的作者声称它通过在运行每个测试之前清理测试类来使测试更加可预测和无状态(测试之间没有依赖关系)。在实践中,特别是在集成测试中,这更像是一种痛苦,而不是一种优势。
顺便说一下,如果在测试中进行一些数据库操作并提交更改,请注意测试依赖性。 JUnit中无法保证执行测试的顺序。这意味着一次测试中的更改不应影响其他测试。