In Grails, how do I mock GrailsDomainBinder in a unit test? - grails

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:
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.
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?

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)

Related

How to declare factory constructor in abstract classes?

I want to declare, but not define a factory constructor in an abstract class.
In my case, I want to create a method that accepts any class that implements a String toJson() method as well as a fromJson(Map<String, dynamic> data) factory constructor.
Is there any way to achieve that in Dart?
I'm looking for something like the following, which is not valid Dart code:
abstract class JsonSerializable {
factory fromJson(Map<String, dynamic> data);
String toJson();
}
I'm afraid that it doesn't work the way you want it to.
Constructors are not part of an interface. They act more like static members.
So, you can't add a factory to the interface, and code wouldn't have any way to call the factory constructor given a type variable extending this type anyway.
So, since constructors cannot be part of interfaces, constructors also cannot be abstract. Being abstract simply means "make the member part of the interface, but no implementation is added to class".
You can declare the factory as a normal method, but then you would only be able to call it when you already have an instance, which likely isn't what you want with a constructor.
The only way to pass code around is as functions or objects with methods. So, if you want to parameterize something by a type which is JsonSerializable, and you want to be able to create such an object, you need to pass a factory function along:
T deserialize<T extends JsonSerializable>(
String json,
T factory(Map<String, dynamic> data),
) {
return factory(jsonDecode(json) as Map<String, dynamic>);
}
You an then call it with:
var myValue = deserialize(jsonString, (x) => MyClass.fromJson(x));
(If MyClass.fromJson had been a static function instead of a constructor, you could just write deserialize(jsonString, MyClass.fromJson), but Dart doesn't yet have constructor tear-offs).
As suggested in the accepted answer, I ended up creating a Serializer<T> type that got implemented by a serializer for each class:
Turns out, this has several benefits over just having toJson/fromJson on the classes directly:
It decouples the serialization logic from the actual classes. That means better code readability because classes only contain methods that relate directly to the class — serializers can even be put into their own files.
Currently, extensions can't create constructors. So having serializers separately makes it possible to write serializers for existing classes, like String or Flutter's Color, where you can't just add a fromColor constructor.
Both these points combined mean it also works well with code generation — the classes are hand-written and the serializer can be generated in a separate file.
Code example:
class Fruit {
Fruit(this.name, this.color);
final String name;
final String color;
}
// in another file
class FruitSerializer extends Serializer<Fruit> {
Map<String, dynamic> toJson(Fruit fruit) {
return ...;
}
Fruit fromJson(Map<String, dynamic> data) {
return Fruit(...);
}
}
An then also pass the serializer to the code that needs it:
someMethod<T>(Serializer<T> serializer, T value) {
...
}
someMethod(FruitSerializer(), someFruit);
final fruit = recreateFruit(FruitSerializer());
Obviously, you can't pass an object that can't be serialized to the code, because the method expects a Serializer<T>.

Grails - filter declared properties from those that mixin seem to add

I'm trying to create a mixin that transforms objects into some other type using using their properties. The mixin looks something like,
class MyMixin {
MyModel transform() {
MyModel model = new MyModel()
this.properties.each { key, value ->
model.addToList(key, value)
}
return model
}
}
Sample usage,
#Mixin(MyMixin)
class OtherModel {
Integer number
String description
}
However, it seems like some properties are getting added under the hood. When I test the number of entries added to the list, it's more that expected. Instead of just having 2 here, I'm getting 5.
I'm ok with the mixin adding properties in the background, but if that's the case, I want to know a way to check declared properties.
For illustration, checkout the test/mixin branch of my sample project in GitHub.
In particular, see the files:
PropertyMixin.groovy
PropertyMixinSpec.groovy

Explicit casting doesn't work in default model binding

I am using ASP.NET MVC2 and Entity Framework. I am going to simplify the situation a little; hopefully it will make it clearer, not more confusing!
I have a controller action to create address, and the country is a lookup table (in other words, there is a one-to-many relationship between Country and Address classes). Let's say for clarity that the field in the Address class is called Address.Land. And, for the purposes of the dropdown list, I am getting Country.CountryID and Country.Name.
I am aware of Model vs. Input validation. So, if I call the dropdown field formLand - I can make it work. But if I call the field Land (that is, matching the variable in Address class) - I am getting the following error:
"The parameter conversion from type
'System.String' to type 'App.Country'
failed because no type converter can
convert between these types."
OK, this makes sense. A string (CountryID) comes from the form and the binder doesn't know how to convert it to Country type. So, I wrote the converter:
namespace App {
public partial class Country {
public static explicit operator Country(string countryID) {
AppEntities context = new AppEntities();
Country country = (Country) context.GetObjectByKey(
new EntityKey("AppEntities.Countries", "CountryID", countryID));
return country;
}
}
}
FWIW, I tried both explicit and implicit. I tested it from the controller - Country c = (Country)"fr" - and it works fine. However, it never got invoked when the View is posted. I am getting the same "no type converter" error in the model.
Any ideas how to hint to the model binder that there is a type converter?
Thanks
A type converter is not the same as an explicit or implicit conversion, it's an object that converts values between various types.
I think you need to create a class inherited from TypeConverter that converts between Country and other types, and apply the TypeConverterAttribute to your class to specify the converter to use :
using System.ComponentModel;
public class CountryConverter : TypeConverter
{
// override CanConvertTo, CanConvertFrom, ConvertTo and ConvertFrom
// (not sure about other methods...)
}
[TypeConverter(typeof(CountryConverter))]
public partial class Country
{
...
}

How do I get the type (class) of a property of a Grails domain object?

I'm trying to dynamically create domain objects in Grails and encountered the problem that for any property referencing another domain object the metaproperty tells me its type is "java.lang.Object" and not the expected type.
For example:
class PhysicalSiteAssessment {
// site info
Site site
Date sampleDate
Boolean rainLastWeek
String additionalNotes
...
is the beginning of a domain class, which references another domain class "Site".
If I try to dynamically find the property types for this class by using this code (in a service):
String entityName = "PhysicalSiteAssessment"
Class entityClass
try {
entityClass = grailsApplication.getClassForName(entityName)
} catch (Exception e) {
throw new RuntimeException("Failed to load class with name '${entityName}'", e)
}
entityClass.metaClass.getProperties().each() {
println "Property '${it.name}' is of type '${it.type}'"
}
then the result is that it recognizes the Java classes, but not the Grails domain class. The output contains the following lines:
Property 'site' is of type 'class java.lang.Object'
Property 'siteId' is of type 'class java.lang.Object'
Property 'sampleDate' is of type 'class java.util.Date'
Property 'rainLastWeek' is of type 'class java.lang.Boolean'
Property 'additionalNotes' is of type 'class java.lang.String'
The problem is that I would like to use the dynamic lookup to find matching objects, e.g. do a
def targetObjects = propertyClass."findBy${idName}"(idValue)
where the propertyClass is retrieved via introspection, idName is the name of the property to look up (not necessarily the database ID) and idValue is the value to find.
It all ends in:
org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingMethodException: No signature of method: static java.lang.Object.findByCode() is applicable for argument types: (java.lang.String) values: [T04]
Is there a way to find the actual domain class for the property? Or maybe some other solution to the problem of finding an instance of a domain class whose type is not given (only a property name that has the type)?
It works if I use the convention that the type name is the property name capitalized ("site"->"Site") to look up the class via the grailsApplication instance, but I would like to avoid that.
Grails allows you to access some meta-information of your domain model via the GrailsApplication instance. You can look it up that way:
import org.codehaus.groovy.grails.commons.ApplicationHolder
import org.codehaus.groovy.grails.commons.DomainClassArtefactHandler
def grailsApplication = ApplicationHolder.application
def domainDescriptor = grailsApplication.getArtefact(DomainClassArtefactHandler.TYPE, "PhysicalSiteAssessment")
def property = domainDescriptor.getPropertyByName("site")
def type = property.getType()
assert type instanceof Class
API:
GrailsApplication
GrailsDomainClass
GrailsDomainClassProperty
You can use GrailsClassUtils.getPropertyType(clazz, propertyName)
The answer above provided by Siegfried became obsolete somewhere around Grails 2.4. ApplicationHolder is obsolete.
Now, you can get real type names from the domainClass property that every domain class has.
entityClass.domainClass.getProperties().each() {
println "Property '${it.name}' is of type '${it.type}'"
}
Note: this answer is not directly to the question but relates enough IMO.
I was banging my head to the wall, ground and surrounding trees when trying to resolve the "generic type" of a collection association:
class A {
static hasMany = {
bees: B
}
List bees
}
Turned out the easiest and yet sound way was mere (and which I did not try but after 3 hours):
A.getHasMany()['bees']

Understanding Dynamic Binding

I understand how the implementation of dynamic binding works and also the difference between static and dynamic binding, I am just having trouble wrapping my brain around the definition of dynamic binding. Basically other than it is a run-time binding type.
Basically, dynamic binding means that the address for a function call is not hard-coded into the code segment of your program when it's translated into assembly language, and is instead obtained from elsewhere, i.e. stack variables, array lookups, etc.
At a higher level, if you have a line of code:
foo(bar) //Calls a funciton
If it can be known at compile time exactly what function this will call, this is static binding. If foo could mean multiple functions depending on things not knowable at compile time, this is dynamic binding.
I understand it being evident in polymorphism. Typically when creating multiple classes that derive from a base class. If each one of the derived classes contains a function that each one uses. The base class can be used to execute a function of the derived classs and it will be properly call the correct function.
For example:
class Animal
{
void talk();
}
class Dog extends Animal
{
public void talk() { System.out.println("woof"); }
}
class Cat extends Animal
{
public void talk() { System.out.println("meow"); }
}
....
Animal zoo[2];
zoo[0] = new Dog();
zoo[1] = new Cat();
for(Animal animalToggle: zoo)
{
animalToggle.talk();
}
will print:
woof
meow
My interpretation hopefully it helps.

Resources