You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Grails 2.4.5中如何模拟带复合ID的MyObject对象?

解决Grails中复合ID对象的单元测试模拟问题

我之前也踩过Grails里复合ID对象单元测试mock的坑,你的问题核心是mockDomain默认对复合主键的支持不够友好,导致查询不到模拟数据。给你两个靠谱的解决办法:

方法一:手动创建并保存对象(推荐)

放弃直接在mockDomain里传数据列表,先初始化mock,再手动创建对象并执行保存操作,让模拟ORM层正确处理复合ID的逻辑:

def setup() {
    // 先初始化mockDomain
    mockDomain(MyObject)
    
    // 手动创建对象并保存,flush确保数据立即写入模拟库
    new MyObject(
        action: 'ACT1', 
        reason: 'REAS1', 
        description: 'First reason'
    ).save(flush: true, failOnError: true)
    
    new MyObject(
        action: 'ACT2', 
        reason: 'REAS2', 
        description: 'Second reason'
    ).save(flush: true, failOnError: true)
    
    // 现在查询就能拿到数据了
    def myObject = MyObject.first()
}

添加failOnError: true还能帮你快速排查保存失败的问题(比如字段约束不满足之类的)。

方法二:显式指定复合ID的映射

如果一定要用mockDomain的列表参数,需要在每个数据map里显式指定id字段,值为包含复合主键字段的map:

def setup() {
    mockDomain(MyObject, [
        [
            id: [action: 'ACT1', reason: 'REAS1'],
            action: 'ACT1', 
            reason: 'REAS1', 
            description: 'First reason'
        ],
        [
            id: [action: 'ACT2', reason: 'REAS2'],
            action: 'ACT2', 
            reason: 'REAS2', 
            description: 'Second reason'
        ]
    ])
    
    def myObject = MyObject.first()
}

这样mockDomain才能正确识别复合主键,后续的first()、findAll()查询才能匹配到数据。

为什么原来的写法不行?

Grails的mockDomain默认是针对单主键对象设计的,它不会自动识别你在domain类里定义的composite: ["action", "reason"]配置,所以直接传的列表数据,模拟ORM层没法把action和reason当作主键来构建查询条件,自然查不到数据。

内容的提问来源于stack exchange,提问作者mcvkr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:58:14