Grails 4.0.3单元测试:内存库保存实体后删除操作异常问题
问题:删除已存在的Metafile时返回404错误
我为文件管理器API编写单元测试,第一个测试方法验证从不存在的part中删除文件的场景,代码如下:
void "Deleting a file from a non existent part" (){ when: request.method = 'DELETE' request.setParameter("partId","1234567891011") request.setParameter("fileId","65465654546654654") controller.deleteMetafiles() then: response.status == 404 response.json.message == "Part not found." //println(response.getJson()) }
该测试运行符合预期。
接下来我尝试测试删除已插入内存数据库的Metafile,但请求始终返回404(提示"Part not found"),和第一个测试的响应一致,明明已经在given块中创建了Metafile。测试代码如下:
void "Deleting a valid file from an existent part" (){ given: new Metafile(id: '1111111111', filename: 'test.pdf', title: '', description: '', uploadedOn: new Date(), partId: '2222222222', uploadedBy: 'Alfred', userId: '333333333').save() when: setupSpec() request.method = 'DELETE' request.setParameter("partId","2222222222") request.setParameter("fileId","1111111111") def model = controller.deleteMetafiles() then: response.status == 200 println("response status") println(response.status) println("response status") }
附完整测试代码:
package br.gov.cmb.cmbarq.tests import br.gov.cmb.cmbarq.controllers.v1.MetafileController import br.gov.cmb.cmbarq.domain.Metafile import grails.testing.web.controllers.ControllerUnitTest import spock.lang.Specification import grails.testing.gorm.DataTest class MetafileControllerSpec extends Specification implements ControllerUnitTest<MetafileController>, DataTest{ def setupSpec() { } def cleanup() { } void "Getting the amount of files from a non existent part"() { when: request.method = 'GET' request.setParameter("partId","1234567891011") controller.getMetafilesAmount() then: response.status == 404 } void "Listing files of an non existent part"() { when: request.method = 'GET' request.setParameter("partId","1234567891011") controller.listMetafiles() then: response.status == 404 } void "Deleting a file from a non existent part" (){ when: request.method = 'DELETE' request.setParameter("partId","1234567891011") request.setParameter("fileId","65465654546654654") controller.deleteMetafiles() then: response.status == 404 response.json.message == "Part not found." //println(response.getJson()) } void "Deleting a valid file from an existent part" (){ given: List <Metafile> sampleMetafiles = [new Metafile(id: '1111111111', filename: 'test.pdf', title: '', description: '', uploadedOn: new Date(), partId: '2222222222', uploadedBy: 'Alfred', userId: '333333333'), new Metafile(id: '1111111112', filename: 'test2.pdf', title: '', description: '', uploadedOn: new Date(), partId: '2222222221', uploadedBy: 'Alfred', userId: '333333334') ] when: request.method = 'DELETE' request.setParameter("partId","2222222222") request.setParameter("fileId","1111111111") controller.deleteMetafiles() then: println(model.size()) model.size() == 1 } }
错误原因及修复方案
未持久化Metafile实例
在完整测试代码的目标测试方法中,仅创建了sampleMetafiles列表,但没有调用save()方法将实例存入内存数据库,导致控制器无法查询到对应数据。错误调用生命周期方法
在单独测试代码的when块中手动调用了setupSpec(),这是Spock的全局初始化方法,会在所有测试执行前运行一次,手动调用会重置测试状态,清空已保存的数据。未注册测试域类
实现DataTest接口时,需要注册要测试的域类,否则GORM无法识别Metafile,导致保存操作不生效。
修复后的测试代码示例
void "Deleting a valid file from an existent part" (){ given: // 保存Metafile到内存数据库,failOnError确保保存失败时抛出异常 new Metafile(id: '1111111111', filename: 'test.pdf', title: '', description: '', uploadedOn: new Date(), partId: '2222222222', uploadedBy: 'Alfred', userId: '333333333').save(failOnError: true) when: request.method = 'DELETE' request.setParameter("partId","2222222222") request.setParameter("fileId","1111111111") controller.deleteMetafiles() then: response.status == 200 // 验证文件已被删除 Metafile.countByPartIdAndId('2222222222', '1111111111') == 0 }
类层面的补充修复
在测试类的setupSpec()中注册域类:
class MetafileControllerSpec extends Specification implements ControllerUnitTest<MetafileController>, DataTest{ def setupSpec() { // 注册要测试的域类 mockDomain(Metafile) } // 其他测试方法... }
内容的提问来源于stack exchange,提问作者D Nunes
相关产品推荐
相关产品推荐

