Grails
  1. Grails
  2. GRAILS-8596

Static Mixins aren't available to unit-tests

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0 final
    • Fix Version/s: 2.2
    • Component/s: Testing
    • Environment:
    • Testcase included:
      yes

      Description

      When running unit tests there doesn't appear to be a consistent (or working) mechanism to apply mixins to JDK classes (and possibly others). Our current project uses several JDK classes that have been mixed-in with other helper methods (example: Date.mixin DateUtils). Domain, service and controller code depends on having these methods available. When testing these methods aren't available even though they have been mixed in.

      The attached bug report contains one domain class and one test which fails when run because Date doesn't contain the monster method that was mixed in with a static initialization block in the same test, see below. I've also tried to mix it in using a @BeforeClass method which appears to work for the first test but all subsequent tests in the same class fail with a 'no method called monster' exception. Using a @Before method works by re-mixing-in DateUtils every time but there appears to be a larger problem. From what I can tell DateUtils is being correctly mixed into Date with a static initializer prior to the MetaClassRegistryCleaner being registered, but for some reason Date doesn't contain the monster method in the test.

      TruckTests.groovy
      @TestFor(Truck)
      class TruckTests {
      
      	static {
      		Date.mixin bug2.DateUtils
      	}
      
      	void testBad() {
      		assert "Monster" == new Date().monster()
      	}
      }
      

      On Grails 1.3.7 we would place references to utility classes that are mixed in with JDK classes into Config.groovy so we knew they would always be there regardless of which environment or which class was loaded first. We wanted to ensure that by the time the project created it's first Date object (via hibernate etc...) that the utility class was already mixed in. In the attached example I didn't do that for simplicity. It doesn't seem to make a difference with the exception of Config.groovy being loaded after the MetaClassRegistryCleaner as been registered.

      Mailing list discussion: http://grails.1312388.n4.nabble.com/Grails-2-0-Global-Mixins-Broken-tt4259490.html#none

        Activity

        Hide
        John Engelman added a comment -

        I have the same issue here with a domain class that is using a @Mixin annotation. The first unit test that the class is used in has the methods available, but they are then removed in the cleanup phase. I've attached a sample project.

        Show
        John Engelman added a comment - I have the same issue here with a domain class that is using a @Mixin annotation. The first unit test that the class is used in has the methods available, but they are then removed in the cleanup phase. I've attached a sample project.
        Hide
        Stan Carney added a comment -

        Almost a year later I tried the attached bug2 project against Grails 2.2.0 and I get zero test failures. It appears this was fixed somewhere between grails 2.0.0 and 2.2.0.

        I believe it can be closed.

        Show
        Stan Carney added a comment - Almost a year later I tried the attached bug2 project against Grails 2.2.0 and I get zero test failures. It appears this was fixed somewhere between grails 2.0.0 and 2.2.0. I believe it can be closed.
        Hide
        Stan Carney added a comment -

        I tested out the mixinUnitTest project and it still fails. It is different from bug2 in that bug2 is using a static mixin on a POJO whereas mixinUnitTest is mixing in a regular Groovy object into a domain class.

        Show
        Stan Carney added a comment - I tested out the mixinUnitTest project and it still fails. It is different from bug2 in that bug2 is using a static mixin on a POJO whereas mixinUnitTest is mixing in a regular Groovy object into a domain class.
        Hide
        Graeme Rocher added a comment -

        This was fixed by the new grails.util.Mixin annotation which uses compile time mixins (Groovy's Mixin annotation uses metaprogramming)

        Show
        Graeme Rocher added a comment - This was fixed by the new grails.util.Mixin annotation which uses compile time mixins (Groovy's Mixin annotation uses metaprogramming)

          People

          • Assignee:
            Graeme Rocher
            Reporter:
            Stan Carney
          • Votes:
            5 Vote for this issue
            Watchers:
            8 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Last Reviewed:

              Development