MeanBean EqualsMethodTester 和 HashCodeMethodTester 的自定义属性工厂

Custom attribute factories for MeanBean EqualsMethodTester and HashCodeMethodTester

是否可以配置自定义工厂以从 org.meanbean.testEqualsMethodTesterHashCodeMethodTester class 生成值?当我将适用于 BeanTester 的配置传递给 EqualsMethodTester 时,我在错误回溯中收到以下消息:

org.meanbean.factories.ObjectCreationException:无法为 属性 [demoUrl] 创建值。

未能为 属性=[demoUrl] 类型=[class java.net.URL] 找到合适的工厂。请注册自定义工厂。

org.meanbean.factories.ObjectCreationException:由于 NoSuchMethodException,无法实例化 [java.net.URL] 类型的对象。

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

(EqualsMethodTesterHashCodeMethodTester 都给出了这个错误。将 "demoUrl" 添加到 insignificantProperties 的列表中对于 EqualsMethodTester().testEqualsMethod() 没有任何区别。逐步执行代码暗示我的 URLFactory.create() 根本没有被调用。)

我没有看到任何将配置传递到 HashCodeMethodTester 的选项。我浏览了以下站点的文档,但既没有找到解决方案,也没有找到对缺失功能的确认: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

(我使用的是 MeanBean v 2.0.3 和 Java 1.8。)

我有以下 class,使用 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;
    }

}

为了处理 URL 字段,我根据 meanbean: failed to test bean with arrays 创建了一个自定义工厂,它适用于 BeanTester 但不适用于 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;
        }
    }
}

我的测试方法如下:

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);
}

我错过了什么?

看起来 EqualsMethodTester().testEqualsMethod() 在特定情况下需要一个 EquivalentFactory,因为 java.net.URL 不提供默认的空构造函数。因此,当为 java.net.URL 调用 BasicNewObjectInstanceFactory.create() 时,调用 clazz.getDeclaredConstructor() 会抛出异常 Method threw 'java.lang.NoSuchMethodException' exception.。 基本上你只需要实现一个 EquivalentFactory。 匿名实现可以是: 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");`

对于哈希码,只需使用等效的工厂即可完成工作。

我测试了它,它正在工作。