Custom attribute factories for MeanBean EqualsMeth

2019-08-31 01:43发布

Is it possible to configure custom factories to generate values for the EqualsMethodTester and HashCodeMethodTester classes from org.meanbean.test? When I pass the Configuration which works for BeanTester to EqualsMethodTester, I get the following messages in the error traceback:

org.meanbean.factories.ObjectCreationException: Failed to create a value for property [demoUrl].

Failed to find suitable Factory for property=[demoUrl] of type=[class java.net.URL]. Please register a custom Factory.

org.meanbean.factories.ObjectCreationException: Failed to instantiate object of type [java.net.URL] due to NoSuchMethodException.

java.lang.NoSuchMethodException: java.net.URL.<init>()

(Both EqualsMethodTester and HashCodeMethodTester give this error. Adding "demoUrl" to the list of insignificantProperties for EqualsMethodTester().testEqualsMethod() makes no difference. Stepping through the code implies my URLFactory.create() isn't called at all.)

I do not see any options for passing the configuration into HashCodeMethodTester. I've skimmed documentation at the following sites, but have found neither a solution nor acknowledgement of the missing functionality: http://meanbean.sourceforge.net/docs/2.0.3/public/org/meanbean/test/EqualsMethodTester.html http://meanbean.sourceforge.net/docs/2.0.3/public/org/meanbean/test/HashCodeMethodTester.html http://meanbean.sourceforge.net/docs/2.0.3/public/org/meanbean/test/ConfigurationBuilder.html http://meanbean.sourceforge.net/docs/2.0.3/Mean_Bean_2.0.3_User_Guide.pdf

(I'm using MeanBean v 2.0.3 and Java 1.8.)

I have the following class, using java.net.URL:

public class Product {
    private String name;
    private URL demoUrl;

    public Product(){
        super();
    }

    public int hashCode() {
        return Objects.hash(getName(), whitehawkSKU);
    }

    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj == this) { 
            return true;
        }
        if (obj.getClass() != getClass()) {
            return false;
        }
        Product other = (Product) obj;
        return Objects.equals(getName(), other.getName());
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public URL getDemoUrl() {
        return demoUrl;
    }

    public void setDemoUrl(URL demoUrl) {
        this.demoUrl = demoUrl;
    }

}

To handle the URL field, I created a custom factory, as per meanbean: failed to test bean with arrays and it works for BeanTester but not for EqualsMethodTester:

import org.meanbean.lang.Factory;

import java.net.MalformedURLException;
import java.net.URL;

public class URLFactory implements Factory<URL> {
    private static int counter = 0;

    @Override
    public URL create() {
        String host = "http://test." + counter + ".url/";
        try {
            return new URL(host);
        }
        catch (MalformedURLException except) {
            return null;
        }
    }
}

My test methods are as follows:

private Configuration configureMeanBeanTests() {
    URLFactory urlFactory = new URLFactory();
    return new ConfigurationBuilder()
        .overrideFactory("demoUrl", urlFactory).build();
}

@Test
public void testAccessors() {
    new BeanTester().testBean(Product.class, configureMeanBeanTests());
}

@Test
public void testEquals() {
    new EqualsMethodTester().testEqualsMethod(
        Product.class,
        configureMeanBeanTests(),
        "name",
        "demoUrl"
    );
}

@Test
public void testHashCode() {
    new HashCodeMethodTester().testHashCodeMethod(Product.class);
}

What am I missing?

1条回答
【Aperson】
2楼-- · 2019-08-31 02:10

It looks like the EqualsMethodTester().testEqualsMethod() needs a EquivalentFactory in that particular case due to the use java.net.URL that does not provide a default empty constructor. So when BasicNewObjectInstanceFactory.create() is called for java.net.URL the call the clazz.getDeclaredConstructor() throw an exception Method threw 'java.lang.NoSuchMethodException' exception.. Basically you just have to implement a EquivalentFactory. An anonymous implementation could be: private EquivalentFactory<Product> productEquivalentFactory = new EquivalentFactory<Product>() { @Override public Product create() { Product p = new Product(); try { p.setDemoUrl(new URL("http://test.1.url/")); } catch (MalformedURLException e) { e.printStackTrace(); } p.setName("test"); return p; } }; It has to be used with the custom configuration that you already have: new EqualsMethodTester().testEqualsMethod(productEquivalentFactory, configureMeanBeanTests(), "demoUrl");`

For the hashcode just use the equivalent factory and it does the job.

I tested it and it is working.

查看更多
登录 后发表回答