2

I have a bunch of subclasses like so:

abstract class Fruit {
    ...

    String getType() {
        // get the discriminator value for this type
        GrailsDomainBinder.getMapping(this.class).discriminator
    }
}

class Apple extends Fruit {
    static mapping = {
        discriminator 'Apple'
    }
}

class Pear extends Fruit {
    static mapping = {
        discriminator 'Pear'
    }
}

In other words, Fruit is a base type with Apple and Pear as subtypes. I exposed a type property that gets the discriminator value that's set in the subclasses.

Now I have a JsonExportService that exports an instance as JSON data. When I'm running the application, this service correctly exports the type property filled in with the discriminator value.

I now need to write a unit test for JsonExportService. Problem is, GrailsDomainBinder doesn't seem to be mocked out in unit tests, and I'm getting NPE: cannot access discriminator property on a null object.

I can work around it in two ways:

  1. Create a static property in each subclass that has the same value as the discriminator:

    class Pear extends Fruit {
        static String type = 'Pear'
        ...
    }
    

    This seems really hacky though, and I'm declaring the same value in two places.

  2. Change the getType() code to:

    GrailsDomainBinder.getMapping(this.class)?.discriminator
    

    This works, but now I'm basically ignoring the discriminator altogether, and the unit test is not 'complete' because it requires a follow-up integration test to ensure that the getType() method is returning the correct value.

Does anyone know of a better, unit-testing-friendly way of getting the discriminator value from the domain mapping?

Daniel T.
  • 37,212
  • 36
  • 139
  • 206

1 Answers1

0

It seems that DefaultGrailsDomainConfiguration is the responsible to initializing the mappings, so you can try:

def domainClass = grailsApplication.getDomainClass(Pear.class.name)
DefaultGrailsDomainConfiguration.configureDomainBinder(grailsApplication, [domainClass] as Set)
println GrailsDomainBinder.getMapping(Pear)