简体   繁体   中英

Grails Spock unit test requires to mock transaction manager

In Grails 3.1.12, I want to unit test a service:

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

Like this:

@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
}

Running the test from the console:

grails> test-app my.PlanServiceSpec -unit

Fails with:

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

and in the test report (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.

Now if I comment out the @Transactional annotation in the service, the test passes, but that's not the intended implementation. I am able to work around the problem by mocking the transaction manager:

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

But this seems very awkward, if not wrong.

Is there some incantation I forgot to invoke?

EDIT: looks similar to an old bug , but it's been closed more than a year.

Have you tried what a comments says that fixes the problem? If not, try to annotate the test class with:

@TestMixin(DomainClassUnitTestMixin)

and then:

service.transactionManager = getTransactionManager()

Was getting the same error in grails 3.3.2 when trying to test transactional service.

adding DataTest interface solved the issue for me.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM