本质:
如何在 JBehave 的JUnit测试中自动回滚 hibernate事务?
问题似乎是JBehave想要SpringAnnotatedEmbedderRunner
但注释测试为@Transactional
需要SpringJUnit4ClassRunner
。
我试图找到一些文档,介绍如何使用SpringAnnotatedEmbedderRunner
实现回滚,或者使用SpringJUnit4ClassRunner
使JBehave工作,但我无法工作。
有没有人有一个(最好是简单的)设置来运行JBehave与Spring和Hibernate以及事务自动回滚的存储?
到目前为止关于我的设置的更多信息:
使用Spring工作JBehave - 但不使用自动回滚:
@RunWith(SpringAnnotatedEmbedderRunner.class)
@Configure(parameterConverters = ParameterConverters.EnumConverter.class)
@UsingEmbedder(embedder = Embedder.class, generateViewAfterStories = true, ignoreFailureInStories = false, ignoreFailureInView = false)
@UsingSpring(resources = { "file:src/main/webapp/WEB-INF/test-context.xml" })
@UsingSteps
@Transactional // << won't work
@TransactionConfiguration(...) // << won't work
// both require the SpringJUnit4ClassRunner
public class DwStoryTests extends JUnitStories {
protected List<String> storyPaths() {
String searchInDirectory = CodeLocations.codeLocationFromPath("src/test/resources").getFile();
return new StoryFinder().findPaths(searchInDirectory, Arrays.asList("**/*.story"), null);
}
}
在我的测试步骤中,我可以很好地@Inject
:
@Component
@Transactional // << won't work
public class PersonServiceSteps extends AbstractSmockServerTest {
@Inject
private DatabaseSetupHelper databaseSetupHelper;
@Inject
private PersonProvider personProvider;
@Given("a database in default state")
public void setupDatabase() throws SecurityException {
databaseSetupHelper.createTypes();
databaseSetupHelper.createPermission();
}
@When("the service $service is called with message $message")
public void callServiceWithMessage(String service, String message) {
sendRequestTo("/personService", withMessage("requestPersonSave.xml")).andExpect(noFault());
}
@Then("there should be a new person in the database")
public void assertNewPersonInDatabase() {
Assert.assertEquals("Service did not save person: ", personProvider.count(), 1);
}
(是的,databaseSetupHelper方法都是事务性的)
PersonProvider基本上是org.springframework.data.jpa.repository.support.SimpleJpaRepository
的包装器。因此可以访问entityManager但是控制事务(使用开始/回滚)不起作用,我想是因为在帮助程序类内部完成的所有@Transactional
。
另外我读到JBehave在不同的上下文中运行?会话?什么?这会导致测试开始的交易失去控制权?相当混乱的东西..
修改
编辑上面的帖子,以反映我目前的知识,缩短整个事情,使问题变得更加明显,设置不那么突兀。
答案 0 :(得分:2)
我认为你可以跳过SpringAnnotatedEmbedderRunner并自己为JBehave提供必要的配置。例如,而不是
@UsingEmbedder(embedder = Embedder.class, generateViewAfterStories = true, ignoreFailureInStories = false, ignoreFailureInView = false)
你可以做到
configuredEmbedder()
.embedderControls()
.doGenerateViewAfterStories(true)
.doIgnoreFailureInStories(false)
.doIgnoreFailureInView(false);
此外:您为什么要回滚交易?通常,您使用JBehave进行验收测试,这些测试在类似生产的环境中运行。例如,您首先在数据库中设置一些数据,通过Browser / Selenium访问它并检查结果。为了实现这一点,必须提交数据库事务。您是否需要在测试后手动清理,您可以在@AfterStories或@AfterScenario注释方法中进行清理。
答案 1 :(得分:2)
我通过手动控制事务范围,在每个方案之后回滚它来使其工作。只需按照官方指南,如何使用Spring和JBehave,然后按照下面的说明进行操作。
@Component
public class MySteps
{
@Autowired
MyDao myDao;
@Autowired
PlatformTransactionManager transactionManager;
TransactionStatus transaction;
@BeforeScenario
public void beforeScenario() {
transaction = transactionManager.getTransaction(new DefaultTransactionDefinition());
}
@AfterScenario
public void afterScenario() {
if (transaction != null)
transactionManager.rollback(transaction);
}
@Given("...")
public void persistSomething() {
myDao.persist(new Foo());
}
}
答案 2 :(得分:1)
我不熟悉JBehave,但看起来你正在寻找这个注释。
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true).
您还可以在testContext中将defaultRollback设置为true。