Hamcrest - Elegant way to test complex object with samepropertyvaluesas - java

I have quite complex object structure (with bunch of primitive fields and object references) and want to test all fields except -a few- of them. As an example;
ComplexObject actual = generateMagically("someInput");
ComplexObject expected = ActualFunction.instance.workMagically(actual);
// we want to be sure that workMagically() would create a new ComplexObject
// with some fields are different than "actual" object.
// assertThat(actual, samePropertyValuesAs(expected)); would check all fields.
// what I want is actually; - notice that "fieldName1" and "fieldName2" are
// primitives belong to ComplexObject
assertThat(actual, samePropertyValuesExceptAs(expected, "fieldName1", "fieldName2"))
Since I don't want to check all fields manually, I believe there must be a way to write that test elegantly. Any ideas?
Cheers.

You should have a look at shazamcrest, a great Hamcrest extension that offers what you need.
assertThat(expected, sameBeanAs(expectedPerson).ignoring("fieldName1").ignoring("fieldName2"));
See https://github.com/shazam/shazamcrest#ignoring-fields

Just pass the list of properties to ignore as 2nd parameter to samePropertyValuesAs.
Hamcrest matcher API
public static <B> Matcher<B> samePropertyValuesAs(B expectedBean, String... ignoredProperties)
e.g.
samePropertyValuesAs(salesRecord,"id")

In general I see two solutions if ComplexObject can be modified by yourself.
You could introduce an interface that represents the properties of ComplexObject that are being changed by ActualFunction. Then you can test that all properties of that new interface have changed. This would require that ComplexObject implements that new interface.
Another approach would be to replace the properties of ComplextObject that are changed by ActualFunction with a new property of a new type that contains all those properties. A better design would then be to let ActualFunction return an instance of the new type.

Last time I had a similar requirements I came to the conclusion that manually writing both code and tests to assert that some values are updated is inherently fagile and error-prone.
I externalized the fields in a bag object and generated the Java source files for both the bag class itself and the copier at compile time. This way you can test actual code (the generator) and have the actual definition of the domain in exactly one place, so the copy code can't be out-of-date.
The language to describe the property can be anything you are comfortable with, from JSON-schema to XML to Java itself (Java example follows - custom annotations are to be consumed from the generator)
public class MyBag {
#Prop public int oh;
#Prop public String yeah;
}

Related

Can I create a DeepCopy of an Java Object/Entity with Mapstruct?

I have a JPA entity (but this question is interesting in general) that consists of multiple child classes (aggregation).
I need to create a new entry in the DB that is 90% identical to the existing one (a few business values and of course the IDs need to be different).
As we need mapstruct for mapping between entity and TO I was thinking "Can mapstruct do this for me?" After Creating a deep copy I could simply update the remaining fields and persist the object.
Writing a copy constructor by hand is error prone (as newly added fields could be forgotten), a generator aproach would be much appreciated.
Yes, you can use #DeepClone:
This Javadoc contains an example:
https://mapstruct.org/documentation/dev/api/org/mapstruct/control/MappingControl.html
#Mapper(mappingControl = DeepClone.class)
public interface CloningMapper {
CloningMapper INSTANCE = Mappers.getMapper( CloningMapper.class );
MyDTO clone(MyDTO in);
}
Yes. But be careful though. If MapStruct discovers the same type on source and target it will simply take (not clone) the source type. Unless you define a method signature for it.
In other words: check the generated code carefully.

Java enum-alternative mapping

Trying to create my own shiny ORM system (not that important information), I'm currently struggling with java inheritance limits. Here is the concept:
public class UserDescriptor implements TableDescriptor {
public static final UserDescriptor INSTANCE = new UserDescriptor();
private UserDescriptor() {
}
public String getTableName() {
return "user";
}
// ======= Columns definition
public static final AbstractColumn<Integer> ID =
new IntegerColumn("id", AbstractColumn.Attribute.NOT_NULL);
public static final AbstractColumn<String> ALIAS =
new StringColumn("alias");
// ... and some more...
}
Hope it's clear enough. These are then used with static import like:
map = JDBCHelper.selectFirst(UserDescriptor.INSTANCE, Arrays.asList(ID, ALIAS));
where the list (2. param) is what I need to fetch from table defined by UserDescriptor. map variable holds custom map, which internally has signature similar to <AbstractColumn<T>, T> and method
public T getValue(AbstractColumn<T> col);
so I'm getting the value then type-safe
Integer id = map.getValue(ID);
String alias = map.getValue(ALIAS);
This concept is currently working, but:
TableDescriptor concept is a bit verbose. I have many tables and need many times to write twice the type and this long start of each column definition
public static final AbstractColumn<Integer>
This line is result of well-know java limitation - not possible to extend enum class. Otherwise the TableDescriptor would be abstract class with field AbstractColumn<T> defined by explicit constructor and every successor would be enum with columns defined within instances.
This would come with following advantages:
Possibility to make whole thing (conditions, returning columns definition, .....) more type-safe, eg. only enum of specific type can be listed in List parameter for select from single table,
better readability and basis for new developers,
getAllColumns functionality can be done without reflection.
This is unfortunately not possible, so you're now my last hope. I know enum inheritance stuff is on SO many times, but I already have already working solution and maybe it's possible to improve it some other way in this specific case..
What may be some kind of hint - these descriptors must now be int the API part of project to selects to be possible. I was struggling with the way I'd put it to impl. and in API I'll let only some enum listing only overview of the columns:
public enum UserTableColumns {
ID,
ALIAS
}
and map it somehow to UserDescriptor - then I'd be able to use in most cases only this enum, but I didn't figure out yet how this should work..
Current signature of selectFisrt method is following:
CustomResultMap selectFirst(TableDescriptor td, List<AbstractColumn<?>> cols);
and one possible modification would be to change List<AbstractColumn<?>> to some list of enum values, which will be mapped to TableDescriptor so I can check that the values are from single table.
Edit: clarification
I'll try to summarize what I understood from your question and the comments:
Your API should contain an enum like UserTableColumn as well as a method that currently looks like T get(AbstractColumn<T>) but should return the correct type based on the generic type of the column. Since AbstractColumn basically is meant to be an implementation detail you'd like to replace that with the enum, e.g. to get something like this (which won't compile): T get(UserTableColumn<T>).
(Please correct me if I made a mistake somewhere.)
The problem with that is that generics are a compile time tool, i.e. the compiler needs to know about the type that is being used. However, enum values can't have generic types and any parameter (e.g. ID(Integer.class)) would not be available at compile time since it's basically an instance (i.e. runtime) value.
Thus you'll need something like AbstractColumn<T> although that might be another class that only contains the generic type (and implements some interface). That probably requires some manual definition or the use of a preprocessor (have a look at how Hibernate does it for its criteria api).

Are there good alternatives for serializing enums in Java?

The Java language benefited much from adding enums to it; but unfortunately they don't work well when sending serialized objects between systems that have different code levels.
Example: assume that you have two systems A and B. They both start of with the same code levels, but at some point the start to see code updates at different points in time. Now assume that there is some
public enum Whatever { FIRST; }
And there are other objects that keep references to constants of that enum. Those objects are serialized and sent from A to B or vice versa. Now consider that B has a newer version of Whatever
public enum Whatever { FIRST; SECOND }
Then:
class SomethingElse implements Serializable { ...
private final Whatever theWhatever;
SomethingElse(Whatever theWhatever) {
this.theWhatever = theWhatever; ..
gets instantiated ...
SomethingElse somethin = new SomethingElse(Whatever.SECOND)
and then serialized and sent over to A (for example as result of some RMI call). Which is bad, because now there will be an error during deserialization on A: A knows the Whatever enum class, but in a version that doesn't have SECOND.
We figured this the hard way; and now I am very anxious to use enums for situations that would actually "perfect for enums"; simply because I know that I can't easily extend an existing enum later on.
Now I am wondering: are there (good) strategies to avoid such compatibility issues with enums? Or do I really have to go back to "pre-enum" times; and don't use enums, but have to rely on a solution where I use plain strings all over the place?
Update: please note that using the serialversionuid doesn't help here at all. That thing only helps you in making an incompatible change "more obvious". But the point is: I don't care why deserialization fails - because I have to avoid it to happen. And I am also not in a position to change the way we serialize our objects. We are doing RMI; and we are serializing to binary; I have no means to change that.
As #Jesper mentioned in the comments, I would recommend something like JSON for your inter-service communication. This will allow you to have more control on how unknown Enum values are handled.
For example, using the always awesome Jackson you can use the Deserialization Features READ_UNKNOWN_ENUM_VALUES_AS_NULL or READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE. Both will allow your application logic to handle unknown enum values as you see fit.
Example (straight from the Jackson doc)
enum MyEnum { A, B, #JsonEnumDefaultValue UNKNOWN }
...
final ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE);
MyEnum value = mapper.readValue("\"foo\"", MyEnum.class);
assertSame(MyEnum.UNKNOWN, value);
After going back and forth regarding different solutions, I figured a solution based on the suggestion from #GuiSim : one can build a class that contains an enum value. This class can
do custom deserialization; thus I can prevent there won't be exceptions during the deserialization process
provide simple methods like isValid() and getEnumValue(): the first one tells you if the enum deserialization actually worked; and the second one returns the deserialized enum (or throws an exception)

Is decorator pattern suitable here

So I have a couple of classes, A, B, C, ... N. And a couple of possible properties, setP(), setQ(), setR(), ... setZ(). Now, each class can have a different combination of properties:
A B C N
- setX - setR - setP - setY
- setY - setZ - setQ - setZ
- setZ - setR
- setS
- setZ
all of the setters return an instance of the object itself so that chaining is possible.
im trying to find an elegant way to solve this problem. i dont want to redefine the tens of properties in each class (code duplication) and i dont wanna use inheritance since the there will be ugly, pointless intermediate classes (BaseABCD -> setZ) and cuz the base class setter will return an instance of type BaseABCD which will not allow full chaining of all properties.
here are some possible things im trying to look into:
somehow define each property as a decorator in an elegant fashion, and compose A something like Base.decorators().addX().addY().addZ().finalize().
define all possible properties in Base and hide non-required properties in derived classes. I dont think this is possible.
Is any of these things possible? or is there a better idea to solve a problem like this one?
More details
The classes are basically different message types used by the application to communicate with an external system. Different messages contain different fields of different types. For instance:
ECHO message:
- Timestamp (DateTime)
- SourceAddress (String)
CHECK RESOURCE message:
- Timestamp (DateTime)
- Resource Identifier (Integer)
MANIPULATE RESOURCE
- Resource Identifier (Integer)
- Operation Type (Enum)
The messages are serialized as a string when transmitted and type information is not retained. So I chose to go with a HashMap<String, String>. Each property corresponds to a key within that class's hashmap. When serializing, I just iterate over all key/value entries in that class's hashmap and produce a string message representation to be sent.
However, I want to enforce types towards the caller code. So I dont want to expose a method like A.set('RESOURCEIDENTIFIER', '123456'). Instead I want to expose methods like A.setResourceIdentifier(123456) and C.setOperation(OperationType.DELETE).
Internally, these setter functions are simply putting a relevant key in the hashmap and assigning a string value to it.
public A setOperation(OperationType operation) {
this.hashmap.put('OPERATION', operation.name());
return this;
}
There are about 40 unique field types and all messages employ a unique subset of these fields. Like A and B contain setTimestamp(). B and C contain setResourceIdentifier(). Only C contains setOperationType(). And so on.
I don't want to redefine these tens of properties in each class over and over again. That's why I want to explore the following two options:
Option 1
Define a Base class with ALL possible properties and in derived A class, override only the required properties to be public. This is do-able. But I want to see if it is possible to implement something like described in option #2.
Option 2
Somehow define decorators and a factory class such that
public ? getA() {
return Base.startDecorating()
.addTimestamp()
.addResourceIdentifier()
.finalize();
}
? objA = Factory.getA()
.setTimestamp(DateTime.now())
.setResourceIdentifier(123456);
Can this be possible? While writing out this question, I realized that Option 1 should be the way to go. It's simple and less error prone. But just out of curiosity I want to know if decorator pattern can be used here. After all, what I have here is a complete set of independent modules (properties) and different ways of assembling them together (the classes).
A decorator is made for something that you can keep adding to. Like a xmas tree. But once the xmas tree is decorated, then you use common methods like turnOn(). Its not made for adding new methods to an existing API. I think you can use regular old inheritance for this. I would also use examples like List. Your Base class can provide the common methods that all will share, and then each other sub-class will add new methods.
To help keep things clean you can add a Factory or a Builder to make things easier.
Here are some examples. Assuming base class is called Base, and sub-classes are one letter named classes, A, B, etc.
Factory example 1.
Base x = factory.getInstance(A.class);
Factory example 2.
Map props = ...;
Base x = factory.getInstance(A.class, props);
Builder example 1.
Base x = new ABuilder().setX(x).setY(y).setZ(z).create();
This involves creating a builder class for each individual sub-class. The sub-class builder classes may or may not inherit from an abstract BaseBuilder class that defines a method with signature public Base create();.
If the setters of the properties have some logic in them which is shared across multiple main classes, a decorator pattern can fit and be a good design approach. If not, e.g. you are sure that all they will ever do is this.x=x or that each class sets a property of some type diffrently then no.
You can define a class for each of the properties, and have your main classes have variables of types of the properties classes. this way when a property is being set on the main class it delegates the job to the setter of the appropriate property class, This way you define the setters of your properties once and use them everywhere. Again, in case you have more logic then this.x=x; in your setters this may be the best idea.
Oh and you can still return this for chainning after delegating the set job to the property class.
Also, if you are lazy and care less for real time performance, you can use reflections to ease the coding of your main classes.
From the names of the properties i would guess you are trying to define different coordinate representations? Why not use one base class with all properties?
Those are actually not that much properties and you can't combine them in random permutations. So why make every thing more complex then necessary?
I don't think Decorator would be a good fit here: the sense of a decorator is to stay transparent. If you define your properties like that, you would have to check (on type or existance of the property) for each and every access.

Javascript file object equivalent in java

I have some javascript code that looks like this
attachmentFiles.push(fileObj);
where fileObj is the file user has selected to upload.
Now if I want to represent in the java/json format, what should be the type of the list?
i.e
public class AttachmentHodler{
List<?> attachmentFiles;
public List<?> getAttachmentFiles() {
return attachmentFiles;
}
public void setAttachmentFiles(List<?> attachmentFiles) {
this.attachmentFiles = attachmentFiles;
}
}
It depends on the purpose of fileObj. Depending on what you want to do with it and what it's responsibilities are you could use:
some specialized Attachement class that you would create. Most versatile approach from the OO perspective. Example: http://ideone.com/H23Za7
An actual File that supports operation like .delete().
just a String to represent the path without any useful functionality.
It depends on what you want to store in your List. You can even choose to use List<?>, which will allow you to store almost anything in it. But if your attachment objects are of type Attachment, I'do go with List<Attachment>. That would allow you to store only Attachment objects in the list.
Since in Javascript there are no classes, it might be worth to mention that in Java, every object is an instance of a "class". Sometimes you define classes yourself, sometimes you re-use classes inside a framework or library.
So there is no general answer to the question, what type your elements will have.

Categories