9

本质:

如何在使用JBehave运行的 JUnit 测试中自动回滚我的休眠事务

问题似乎是 JBehave 想要但根据需要SpringAnnotatedEmbedderRunner注释测试。@TransactionalSpringJUnit4ClassRunner

我试图找到一些关于如何使用 实现回滚SpringAnnotatedEmbedderRunner或使 JBehave 工作的文档,SpringJUnit4ClassRunner但我都无法工作。

有没有人有一个(最好是简单的)设置来运行带有 Spring 和 Hibernate 以及事务自动回滚的 JBehave 故事?



到目前为止有关我的设置的更多信息:

使用 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在该助手类内部完成的所有 s 。

我还读到 JBehave 在不同的上下文中运行?会话?什么?这会导致对测试开始的事务失去控制?很混乱的东西。。


编辑:

编辑上面的改写帖子以反映我当前的知识并缩短整个内容,以便问题变得更加明显并且设置不那么突兀。

4

3 回答 3

2

我认为您可以跳过 SpringAnnotatedEmbedderRunner 并自己为 JBehave 提供必要的配置。例如,而不是

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

你可以做

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

另外:为什么要回滚事务?通常,您使用 JBehave 进行验收测试,这些测试在类似生产的环境中运行。例如,您首先在数据库中设置一些数据,通过浏览器/Selenium 访问它并检查结果。为此,必须提交数据库事务。测试后是否需要手动清理,可以在 @AfterStories 或 @AfterScenario 带注释的方法中进行。

于 2012-06-22T08:36:23.000 回答
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());
    }
}
于 2014-07-09T21:34:22.807 回答
1

我不熟悉 JBehave,但您似乎正在搜索此注释。

@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true).

您还可以在 testContext 中将 defaultRollback 设置为 true。

于 2012-05-14T14:18:24.487 回答