【问题标题】:Grails 1.3.7 to Grails 2.2 upgrade, Unit tests now fail with missing GORM methodsGrails 1.3.7 到 Grails 2.2 升级,单元测试现在因缺少 GORM 方法而失败
【发布时间】:2013-02-05 16:03:48
【问题描述】:

我正在将应用程序从 Grails 1.3.7 升级到 2.2

到目前为止,它相对轻松且直接。

直到我们开始运行单元测试。

在 1.3.7 下,所有测试都通过了。

在 2.2 下,现在大约有一半失败了。测试没有改变,它们仍然是老式的 mockDomain...

我最担心的是一些领域类缺少基本的 gorm 功能。

.list 和 .get 之类的东西

失败:testList_NoMaxSpecified_10Shown(com.litle.bldvwr.StreamControllerTests) | groovy.lang.MissingMethodException:没有方法签名:>com.litle.bldvwr.Stream.list() 适用于参数类型:() 值:[] 可能的解决方案:list()、list()、list()、list(java.lang.Object)、list(java.util.Map)、>list(java.lang.Object)

失败:>testAddFailureOutputToHappyPathWithIntegrationFailure(com.litle.bldvwr.LogParserServiceTests) | groovy.lang.MissingMethodException:没有方法签名:>com.litle.bldvwr.Result.get() 适用于参数类型:() 值:[] 可能的解决方案:get(java.io.Serializable)、get(java.lang.Object)、>get(java.io.Serializable)、getId()、grep()、grep(java.lang.Object)

此类故障的一般模式是:

mockDomain(Phase, [new Phase(id:1, name: 'xxx')])       
mockDomain(Result, [new Result(id:1, phase: Phase.get(1), failureOutput:"")])          
logParserService.addFailureOutputTo(Result.get(1))

这是导致无签名错误的最后一次获取。

虽然我们打算开始使用新的单元测试功能,但我希望避免重写当前的 500 多个测试。

想法,想法?

-克拉克

【问题讨论】:

    标签: unit-testing grails-2.0


    【解决方案1】:

    在域对象的测试中使用新的 @Mock() 注释将注入所有预期的模拟 GORM 方法,您甚至可以只 save() 域对象而不是在 mockDomain() 调用中提供列表。

    @Mock([Result, Nightly])
    class MyTests {
      void testSomething() {
        def night = new Nightly( name:'nightly1')
        night.id=1
        night.save(validate: false)
    
        assert Nightly.get(1).name == 'nightly1'
    
        assert Result.count() == 0
    
        new Result(status: Constants.SUCCESS, type: Constants.INTEGRATION, 
          nightly: Nightly.get(1)).save(validate: false)
    
        assert Result.count() == 1
        assert Result.findByStatus(Constants.SUCCESS) != null // yay dynamic finders!
    
      }
    }
    

    http://grails.org/doc/latest/guide/testing.html#unitTestingDomains

    您必须将所有测试更新为新方法,但它比旧的 1.3 方法要好得多

    【讨论】:

      【解决方案2】:

      这就是我们发现的。

      使用 1.3,您可以:

        {
         mockDomain(Nightly, [new Nightly(id: 7)])
          mockDomain(Result, [
              new Result(status: Constants.SUCCESS, 
              type: Constants.INTEGRATION, nightly: Nightly.get(7))
          ])
          service.callSomething(results, Nightly.get(7))
          assert result==Nightly.get(7).property
      

      它会工作得很好。你有一个 id 为 7 的 Mock 域对象,并且 get 可以正常工作。

      从那以后,有些东西发生了变化,你不能再设置 id 的一部分了。

      你需要做的是:

      night = new Nightly( name:'nightly1')
          night.id=1
          mockDomain(Nightly, [night])
          mockDomain(Result, [
              new Result(status: Constants.SUCCESS, type: Constants.INTEGRATION, nightly: Nightly.get(1))
          ])
      

      这主要是正确设置模拟。

      我们接下来遇到的问题是,在 mockDomain 调用之外,Nightly.get() 不起作用。

      所以现在我们需要将“模拟”域保存在局部变量中,以便进行后期操作比较和检查。

      不是一个完全糟糕的解决方案,但没有我们希望的那么优雅。

      【讨论】:

      • 必须显式分配 id 是因为默认情况下某些字段不再可从构造函数映射中绑定。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多