Grails 3 控制器单元测试:域 class 验证在 ControllerUnitTest 中不起作用

Grails 3 Controller Unit Testing: Domain class validation not working in a ControllerUnitTest

我正在将继承的 Grails 2 应用程序升级到 3.3.10。我们有依赖域 class 验证来控制逻辑流的控制器方法,但是当在 Grails 3运行

中时,我们无法让 DomainClass 验证在 ControllerUnitTests 中工作

例如, GiftRecipientAddress 是域类,RecipientAddress.hasErrors() 用于根据 RecipientAddress 约束进行验证。

    def confirmAddress() {
        Gift gift = Gift.get(params.giftId)
        if (!gift) {
            render(view: "index", model: [invalid: true])
            return
        }

        recipientAddress = recipientAddressService.storeAddressInformation(params, gift)
        if (recipientAddress.hasErrors()) {
            render(view: "index", model: getAddressErrorModel(gift, recipientAddress))
            return;
        } else {
            return [
                    recipientAddress    : recipientAddress,
                    gift                : gift
            ]
        }
    }

在下面的测试中,当我调试控制器方法时,它会执行所有预期的操作,但 recipientAddress.hasErrors() 总是 returns true 并且测试失败。

即:

@Transactional
class GiftDetailsControllerTest extends Specification implements ControllerUnitTest<GiftDetailsController> {

    @Shared
    @AutoCleanup
    SimpleMapDatastore dataStore = new SimpleMapDatastore([ConnectionSource.DEFAULT, "reporting"],
            RecipientAddress, Gift)

    def setup() {
        controller.recipientAddressService = Mock(RecipientAddressService)
    }

    void "test RecipientAddress Bad PhoneNumber"() {
        given:
        RecipientAddress recipientAddress = new RecipientAddress(
                phone: '123-456-789'
        )

        UnitTestDataFactory dataFactory = UnitTestDataFactory.getDataFactory()
        Gift gift = dataFactory.getMockGift()
        gift.save()

        params.giftId = gift.id

        when:
        recipientAddress.validate()
        controller.confirmAddress()

        then:
        recipientAddress.hasErrors()
        recipientAddress.getErrors().getFieldError('phone')
        1 * controller.recipientAddressService.storeAddressInformation(params, gift) >> recipientAddress
        view == '/giftDetails/index'
    }
}

实施 DataTest 即:...implements ControllerUnitTest<GiftDetailsController>, DataTest { 修复了 DomainClass 验证,但破坏了控制器获取已保存礼物的能力。

有没有办法让 DomainClass 验证在 ControllerUnit 测试中起作用?


修复

使用 mockDomains 实现了 DataTest 并且必须删除自定义数据存储。

@Transactional
class GiftDetailsControllerTest extends Specification implements ControllerUnitTest<GiftDetailsController>, DataTest {

//    @Shared
//    @AutoCleanup
//    SimpleMapDatastore dataStore = new SimpleMapDatastore([ConnectionSource.DEFAULT, "reporting"], RecipientAddress, Gift)

    void setupSpec() {
        mockDomains RecipientAddress, Gift
    }

....

Is there a way get DomainClass validation working in a ControllerUnit test?

是的。

您可能想要这样的东西...

class GiftDetailsControllerTest extends Specification implements ControllerUnitTest<GiftDetailsController>, DataTest {

    Class[] getDomainClassesToMock() {
        [Gift]
    }

    // ...
}