Grails
  1. Grails
  2. GRAILS-8773

GrailsMock does not correctly handle classes with metaClass.getProperty() implemented (like grails.util.Node())

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0 final
    • Fix Version/s: 2.0.2, 2.1-RC1
    • Component/s: Testing
    • Labels:
      None
    • Environment:
      grails 2.0, Java 1.6.0 b29, Mac OSX 10.7.3
    • Testcase included:
      yes

      Description

      GrailsMock was changed with GRAILS-7448 from getting the types of parameters on mocked methods from parameter.getClass() to parameter.class. This was done to fix cases where the instance of a parameter passed in was itself a GrailsMock and resulted in undemanded methods being called. However, this caused a regression with classes that implement getProperty() in their metaClass and override the behavior such that it.class != it.getClass().

      I was attempting to make a change and a test and submit a pull request, but I cannot immediately determine how to go about this. The mocked class will look and act like the class being mocked (e.g. new GrailsMock(String).createMock() instanceof String == true) so I don't know how to vary the behavior to fix the regression and allow GrailsMock's to also be parameters to other demanded methods.

      Any thoughts?

        Activity

        Hide
        Michael Cameron added a comment -

        I added a quick workaround (and the only one I could think of right now) to fix the regression while keeping the changes for GRAILS-7448 working.

        https://github.com/grails/grails-core/pull/164

        As you can see in the pull request, I check to see if it.class is an instanceof a Class, and only if not, then call getClass() instead. This should work in the case where a GrailsMock is a parameter, and in the case where the parameter implements getProperty() in the metaClass and overrides ".class". The only edge case where this would still seem to fail, is if getProperty() returns a java.lang.Class, but it is not the class of the object, or getMethod() is overridden in the metaClass "getClass()" is intercepted and returns something other than the class.

        Show
        Michael Cameron added a comment - I added a quick workaround (and the only one I could think of right now) to fix the regression while keeping the changes for GRAILS-7448 working. https://github.com/grails/grails-core/pull/164 As you can see in the pull request, I check to see if it.class is an instanceof a Class, and only if not, then call getClass() instead. This should work in the case where a GrailsMock is a parameter, and in the case where the parameter implements getProperty() in the metaClass and overrides ".class". The only edge case where this would still seem to fail, is if getProperty() returns a java.lang.Class, but it is not the class of the object, or getMethod() is overridden in the metaClass "getClass()" is intercepted and returns something other than the class.
        Hide
        Graeme Rocher added a comment -

        Thanks!

        Show
        Graeme Rocher added a comment - Thanks!

          People

          • Assignee:
            Graeme Rocher
            Reporter:
            Michael Cameron
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development