Grails Spock单元测试需要模拟事务管理器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Grails Spock单元测试需要模拟事务管理器相关的知识,希望对你有一定的参考价值。

在Grails 3.1.12中,我想对服务进行单元测试:

@Transactional
class PlanService {
    List<Plan> getPlans(Map params) {
        def currentUser = (User)springSecurityService.getCurrentUser()
        return Plan.findAllByCompany(currentUser.employer, params)
    }
}

像这样:

@TestFor(PlanService)
@Mock([Plan, User, Company])
class PlanServiceSpec extends Specification {
    void "Retrieve plan from the current user"() {
        setup:
        // create and save entities here

        when: "the plans are retrieved"
        def params = null
        def plans = service.getPlans(params)

        then: "the result should only include plans associated to the current user's company"
        plans.size() == 2
}

从控制台运行测试:

grails> test-app my.PlanServiceSpec -unit

失败:

my.FundingPlanServiceSpec > Retrieve plan from the current user FAILED
java.lang.IllegalStateException at PlanServiceSpec.groovy:48

并在测试报告(html)中:

java.lang.IllegalStateException: No transactionManager was specified.
Using @Transactional or @Rollback requires a valid configured transaction manager.
If you are running in a unit test ensure the test has been properly configured
and that you run the test suite not an individual test method.

现在,如果我在服务中注释掉@Transactional注释,测试就会通过,但这不是预期的实现。我可以通过模拟事务管理器来解决这个问题:

service.transactionManager = Mock(PlatformTransactionManager) {
    getTransaction(_) >> Mock(TransactionStatus)
}

但这似乎很尴尬,如果不是错的话。

我忘了援引一些咒语吗?

编辑:看起来类似于an old bug,但它关闭了一年多。

答案

您是否尝试过注释解决问题的方法?如果没有,请尝试使用以下命令注释测试类:

@TestMixin(DomainClassUnitTestMixin)

然后:

service.transactionManager = getTransactionManager()
另一答案

在尝试测试事务性服务时,在grails 3.3.2中得到了相同的错误。

添加DataTest界面为我解决了这个问题。

class HelloServiceSpec extends Specification implements ServiceUnitTest<HelloService>, DataTest { }

以上是关于Grails Spock单元测试需要模拟事务管理器的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spock 进行 Grails 测试 - 选择哪个模拟框架?

IntelliJ IDEA 的零覆盖:带有 Spock 单元测试的 Grails

Grails 2.3 使用 IVY 解析器进行单元测试

如何在 Spock 控制器测试中模拟 Grails 请求对象方法

Grails / Spock:如何在类中模拟从类本身调用方法的单个方法?

如何使用 Spock 测试 Grails 服务?