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?
It looks like the
EqualsMethodTester().testEqualsMethod()
needs a EquivalentFactory in that particular case due to the usejava.net.URL
that does not provide a default empty constructor. So whenBasicNewObjectInstanceFactory.create()
is called forjava.net.URL
the call theclazz.getDeclaredConstructor()
throw an exceptionMethod 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.