Combining JBehave with SpringJUnit4ClassRunner to enable transaction rollback

hibernate, java, jbehave, junit, spring

Solution

I think you can skip the SpringAnnotatedEmbedderRunner and provide the necessary configuration to JBehave yourself. For example instead of

@UsingEmbedder(embedder = Embedder.class, generateViewAfterStories = true, ignoreFailureInStories = false, ignoreFailureInView = false)

you can do

configuredEmbedder()
.embedderControls()
.doGenerateViewAfterStories(true)
.doIgnoreFailureInStories(false)
.doIgnoreFailureInView(false);

Besides: why do you want to rollback the transaction? Typically you are using JBehave for acceptance tests, which run in a production-like environment. For example you first setup some data in the database, access it via Browser/Selenium and check for the results. For that to work the DB transaction has to be committed. Do you need to clean-up manually after your tests, which you can do in @AfterStories or @AfterScenario annotated methods.

Problem

Essence: How can I auto-rollback my hibernate transaction in a JUnit Test run with JBehave? The problem seems to be that JBehave wants the `SpringAnnotatedEmbedderRunner` but annotating a test as `@Transactional` requires the `SpringJUnit4ClassRunner`. I've tried to find some documentation on how to implement either rollback with `SpringAnnotatedEmbedderRunner` or to make JBehave work using the `SpringJUnit4ClassRunner` but I couldn't get either to work. Does anyone have a (preferably simple) setup that runs JBehave storries with Spring and Hibernate and transaction auto-rollback? Further infos about my setup so far: Working JBehave with Spring - but not with auto-rollback: ``` @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); } } ``` In my test steps I can `@Inject` everything nicely: ``` @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); } ``` (yes, the databaseSetupHelper methods are all transactional) PersonProvider is basicly a wrapper around `org.springframework.data.jpa.repository.support.SimpleJpaRepository`. So there is access to the entityManager but taking control over the transactions (with begin/rollback) didn't work, I guess because of all the `@Transactional`s that are done under the hood inside that helper class. Also I read that JBehave runs in a different context?session?something? which causes loss of controll over the transaction started by the test? Pretty confusing stuff.. edit: Editet the above rephrasing the post to reflect my current knowledge and shortening the whole thing so that the question becomes more obvious and the setup less obstrusive.

Original source