2016-11-06 55 views
0

我正在写一个简单的集成测试,我打算模拟删除失败。如何覆盖gorm删除方法进行测试?

控制器只需从数据库中提取记录并将其删除,如下所示。

def deleteItem(id){ 


    def item = Item.get(id) 

    item.delete() 

} 

现在,我想模拟删除失败与下面的代码

void testDeleteItem_FailDeleteFlushSaveFail(){ 


    Item.metaClass.delete = { Map params -> 

     throw new ValidationException("Failed!!") 

    } 



    def model = controller.deleteItem(mp.id) 


    assertEquals controller.flash.message, "Sorry an error occured when deleting!!" 



    GroovySystem.metaClassRegistry.removeMetaClass(Item.class) 



} 

但由于方法不更换测试失败。即在删除时不会引发异常。我猜测问题出在我的元类中。我怎样才能使它在调用删除时抛出异常?我感谢任何帮助!谢谢!

回答

-1

尝试,使用:

Item.metaClass.'static'.delete = { Map params -> 
    throw new ValidationException("Failed!!") 
} 
0

这是因为你应该使用

Item.metaClass.delete = { 

     throw new ValidationException("Failed!!") 

    } 

而不是

Item.metaClass.delete = { Map params -> 

     throw new ValidationException("Failed!!") 

    } 
0

首先,我不认为这个问题应该是最低票数。对于您想要测试程序如何对失败做出反应的场景,这是一个有效的问题。

有几件事错在这里:

  • Domain.delete不会抛出validationExceptions。另外ValidationExceptions由两个参数(String msg,Errors error)构造而成。您需要向您的域类添加自定义错误并将域类传入。再次,这对删除没有意义,因为谁需要在删除时验证对象? 不知道你正在运行的版本,但这里是2.5.1(Grails 2.5.1 docs - 见7.3.2删除对象)的文档

    高清P = Person.get(1) 尝试{ p.delete(齐平:true) } catch(org.springframework.dao.DataIntegrityViolationException e){ flash.message =“无法删除人员$ {p.name}” redirect(action:“show”,id:p.id) }

  • 其次,删除(failOnError:true)。我不确定这是否做任何事情。相反,你应该在try catch中包围你的delete方法,并使用flush:true选项。

    try{ 
        item.delete(flush:true) 
    }catch(DataIntegrityViolationException e){ 
        flash.message = "Sorry an error occurred when deleting!!" 
    } 
    
  • 第三,mp.id来自哪里?我们是否遗漏了测试文件的一部分。如果不是,您的测试似乎依赖于已经存在的数据。即使在集成测试中,为了防止由于缺少数据而造成的测试污染和失败的测试,您也可以单独为每项测试创建数据。

  • 最后,我还没有能够在我的集成测试中正确metaClass域类本身...所以我会推荐你​​metaClass域测试中的实例。下面是一个例子: 忘了包括 '地图PARAMS - >'

    //creating test data 
    def item = new Item(name: 'testName') 
    
    def model = controller.deleteItem(item.id) 
    
    item.metaClass.delete = {Map params -> 
        throw new DataIntegrityViolationException('Some error message') 
    } 
    
    assertEquals controller.flash.message, "Sorry an error occurred when deleting!!" 
    

    编辑1只注意在元类闭合:

MetaClass的域实例方法。 (在所有版本的grails中可能都不需要,因为这些方法在版本中的编译方式有所不同)