Skip to content
This repository was archived by the owner on Aug 8, 2020. It is now read-only.
Sebastian Gröbler edited this page Mar 1, 2015 · 11 revisions

Why is the HashCodeIntegrityTester asserting, that a property is missing, when it is actually implemented in the hashCode method?

The HashCodeIntegrityTester can lead to false positives if the hashCode implementation returns very weak hash codes. One reason for weak hashCodes is a missing prime multiplication, or a too small prime.

Why is it not possible to test immutable beans?

In order to answer that question you need to understand the way the Beast is working. Basically it uses public setters of the class under test to mutate its inner state and compare the result of the method under test (e.g. equals) for each changed property to the result of a un-mutated reference object which is considered to be set with default values. So if you want to test a class which is actually not mutable from outside like java.lang.String we have no way to set the data.

Immutable objects are usually created by passing all necessary data to the constructor. The current implementation of the Beast does only support testing of java classes which do provide a default constructor (with no parameters), which by the way is part of the java beans convention.

What can I do, if my class under test is having properties of which the classes do not provide a default constructor?

The instantiation of classes without a default constructor is currently not supported by the Beast. We recommend to use the InstanceProvider API to pass a custom defined “dirty” and “default” object to the test builder.

What can I do, if my class under test is having properties of which the types are final classes?

The instantiation of test objects for properties of which the classes are final is not possible. Use the InstanceProvider API to pass a custom defined “dirty” and “default” object to the test builder. By the way, the Beast uses default InstanceProviders for properties of types Byte, Boolean, Character, Short, Integer, Long, Float, Double, Object and String, all of which can be overridden by adding custom InstanceProviders to the test builder.

Why is my custom InstanceProvider not used?

A common reason may be that you provided a custom InstanceProvider for class of a property, which is actually not the exact type of a property, but a super-class. Try using the InstanceProvider constructor which offers a third parameter named instanceClass to specify the interface or abstract class you want this InstanceProvider to be used for. If you do not specify the instanceClass explicitly the Beast will use the actual class of the dirty/default object.

Example:

class Foo {
    private Set<Integer> bar;
    ...
}  

class Test {

    @Test
    public void test() {
        final Set<Integer> default = Sets.newHashSet(0);
        final Set<Integer> dirty = Sets.newHashSet(1);

        // this will not work
        final InstanceProvider<Set<Integer> instanceProvider = new InstanceProvider(default, dirty);

        // this will work
        final InstanceProvider<Set<Integer> instanceProvider = new InstanceProvider(default, dirty, Set.class);

        ...
        final EqualsIntegrityTestBuilder builder = new EqualsIntegrityTestBuilder();
        builder.addInstanceProvider(instanceProvider);

        final EqualsIntegrityTest test = builder.create();
        test.run();
        ...
    }
}

How can I add multiple InstanceProviders of the same class to be used for different properties?

Per default there is only one InstanceProvider for each type, however to can specify that an InstanceProvider can be used for a specific property by providing its name in the constructor of the InstanceProvider.

Why is my custom InstanceProvider overridden by another custom InstanceProvider?

The InstanceProvider implements equals and hashCode based on its instanceClass, which is either explicitly provided through the constructor or derived from the provided default/dirty instance and, if provided, on the propertyName. This means if you add more than one InstanceProvider for the same class, the last added one wins. The same applies for providing InstanceProviders with propertyNames. So you can only specify InstanceProviders on per class and if needed on a per property level. Keep in mind that adding InstaceProviders for differently typed generic classes will also override each other because generics are erased at compile time in java. So an InstanceProvider for a Set of Integer and an InstanceProvider for a Set of String are considered equal. Use propertyNames to differentiate.

Why is there no support for “addIncludedPropertyNames”, while there is an “addExcludedPropertyNames” on the test builders?

The main reason behind the development of the Beast was to have an utility which provides the feature to automatically detect that methods like equals, hashCode and toString have not been altered after adding/removing a property to a java bean-like class. So in order to detect this one must use a black-list-approach (excluded properties) instead of a white-list-approach (included properties). Though this may seem unhandy when working with entities which have a lot of properties and implement hashCode and equals only based on the unique identifier (primary key) of the class, we do think that it is worth to write down all the to be excluded properties in a test class to make excluding properties an explicit choice rather than a coincidence.

Why are only public settable properties detectable by the tests?

TODO

How can I test objects which contain arrays?

TODO