Java 如何测试dto和实体类

Java 如何测试dto和实体类,java,junit,Java,Junit,这里是一个抽象类和两个实体/dto测试类。 行COVARGE不递增。 如何(使用xUnit)对具有内部私有方法、字段或嵌套类的类进行单元测试? 我还需要增加dto和实体类的行覆盖率 public abstract class EntityDtoTraverser<T> { /** A map of default mappers for common objects. */ private static final ImmutableMap<Class<?>, S

这里是一个抽象类和两个实体/dto测试类。 行COVARGE不递增。 如何(使用xUnit)对具有内部私有方法、字段或嵌套类的类进行单元测试? 我还需要增加dto和实体类的行覆盖率

public abstract class EntityDtoTraverser<T> {

/** A map of default mappers for common objects. */
private static final ImmutableMap<Class<?>, Supplier<?>> DEFAULT_MAPPERS;

static {
    final Builder<Class<?>, Supplier<?>> mapperBuilder = ImmutableMap.builder();

    /* Primitives */
    mapperBuilder.put(int.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return 0;
        }
    });
    mapperBuilder.put(double.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return 0.0d;
        }
    });
    mapperBuilder.put(float.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return 0.0f;
        }
    });
    mapperBuilder.put(long.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return 0l;
        }
    });
    mapperBuilder.put(boolean.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return true;
        }
    });
    mapperBuilder.put(short.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return (short) 0;
        }
    });
    mapperBuilder.put(byte.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return (byte) 0;
        }
    });
    mapperBuilder.put(char.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return (char) 0;
        }
    });

    mapperBuilder.put(Integer.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return Integer.valueOf(0);
        }
    });
    mapperBuilder.put(Double.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return Double.valueOf(0.0);
        }
    });
    mapperBuilder.put(Float.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return Float.valueOf(0.0f);
        }
    });
    mapperBuilder.put(Long.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return Long.valueOf(0);
        }
    });
    mapperBuilder.put(Boolean.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return Boolean.TRUE;
        }
    });
    mapperBuilder.put(Short.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return Short.valueOf((short) 0);
        }
    });
    mapperBuilder.put(Byte.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return Byte.valueOf((byte) 0);
        }
    });
    mapperBuilder.put(Character.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return Character.valueOf((char) 0);
        }
    });

    mapperBuilder.put(BigDecimal.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return BigDecimal.ONE;
        }
    });
    mapperBuilder.put(Date.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return new Date();
        }
    });

    /* Collection Types. */
    mapperBuilder.put(Set.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return Collections.emptySet();
        }
    });
    mapperBuilder.put(SortedSet.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return Collections.emptySortedSet();
        }
    });
    mapperBuilder.put(List.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return Collections.emptyList();
        }
    });
    mapperBuilder.put(Map.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return Collections.emptyMap();
        }
    });
    mapperBuilder.put(SortedMap.class, new Supplier<Object>() {
        @Override
        public Object get() {
            return Collections.emptySortedMap();
        }
    });

    DEFAULT_MAPPERS = mapperBuilder.build();
}

/** The get fields to ignore and not try to test. */
private final Set<String> ignoredGetFields;

/**
 * A custom mapper. Normally used when the test class has abstract objects.
 */
private final ImmutableMap<Class<?>, Supplier<?>> mappers;

/**
 * Creates an instance of {@link EntityDtoTraverser} with the default ignore fields.
 */
protected EntityDtoTraverser() {
    this(null, null);
}

/**
 * Creates an instance of {@link EntityDtoTraverser} with ignore fields and additional custom mappers.
 *
 * @param customMappers Any custom mappers for a given class type.
 * @param ignoreFields The getters which should be ignored (e.g., "getId" or "isActive").
 */
protected EntityDtoTraverser(Map<Class<?>, Supplier<?>> customMappers, Set<String> ignoreFields) {
    this.ignoredGetFields = new HashSet<String>();
    if (ignoreFields != null) {
        this.ignoredGetFields.addAll(ignoreFields);
    }
    this.ignoredGetFields.add("getClass");

    if (customMappers == null) {
        this.mappers = DEFAULT_MAPPERS;
    } else {
        final Builder<Class<?>, Supplier<?>> builder = ImmutableMap.builder();
        builder.putAll(customMappers);
        builder.putAll(DEFAULT_MAPPERS);
        this.mappers = builder.build();
    }
}

/**
 * Calls a getter and verifies the result is what is expected.
 *
 * @param fieldName The field name (used for error messages).
 * @param getter The get {@link Method}.
 * @param instance The test instance.
 * @param expected The expected result.
 *
 * @throws IllegalAccessException if this Method object is enforcing Java language access control and the underlying
 *             method is inaccessible.
 * @throws IllegalArgumentException if the method is an instance method and the specified object argument is not an
 *             instance of the class or interface declaring the underlying method (or of a subclass or implementor
 *             thereof); if the number of actual and formal parameters differ; if an unwrapping conversion for
 *             primitive arguments fails; or if, after possible unwrapping, a parameter value cannot be converted to
 *             the corresponding formal parameter type by a method invocation conversion.
 * @throws InvocationTargetException if the underlying method throws an exception.
 */
private void callGetter(String fieldName, Method getter, T instance, Object expected)
        throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {

    final Object getResult = getter.invoke(instance);

    if (getter.getReturnType().isPrimitive()) {
        /* Calling assetEquals() here due to autoboxing of primitive to object type. */
        assertEquals(fieldName + " is different", expected, getResult);
    } else {
        /* This is a normal object. The object passed in should be the exactly same object we get back. */
        assertSame(fieldName + " is different", expected, getResult);
    }
}

/**
 * Creates an object for the given {@link Class}.
 *
 * @param fieldName The name of the field.
 * @param clazz The {@link Class} type to create.
 *
 * @return A new instance for the given {@link Class}.
 *
 * @throws InstantiationException If this Class represents an abstract class, an interface, an array class, a
 *             primitive type, or void; or if the class has no nullary constructor; or if the instantiation fails
 *             for some other reason.
 * @throws IllegalAccessException If the class or its nullary constructor is not accessible.
 *
 */
private Object createObject(String fieldName, Class<?> clazz) {

  try {      
      final Supplier<?> supplier = this.mappers.get(clazz);
      if (supplier != null) {
          return supplier.get();
      }

      if (clazz.isEnum()) {
          return clazz.getEnumConstants()[0];
      }
      
      return clazz.newInstance();        
    } catch (IllegalAccessException e) {
        return null;
    } catch (InstantiationException e) {
        return null;
    }
}

/**
 * Returns an instance to use to test the get and set methods.
 *
 * @return An instance to use to test the get and set methods.
 */
protected abstract T getInstance();

/**
 * Tests all the getters and setters. Verifies that when a set method is called, that the get method returns the
 * same thing. This will also use reflection to set the field if no setter exists (mainly used for user immutable
 * entities but Hibernate normally populates).
 *
 * @throws Exception If an expected error occurs.
 */
@Test
public void testGettersAndSetters() throws Exception {
    /* Sort items for consistent test runs. */
    final SortedMap<String, GetterSetterPair> getterSetterMapping = new TreeMap<String, GetterSetterPair>();

    while (true) {
    final T instance = getInstance();
    
    if (instance == null)
        break;
    
    for (final Method method : instance.getClass().getMethods()) {
        final String methodName = method.getName();

        if (this.ignoredGetFields.contains(methodName)) {
            continue;
        }

        String objectName;
        if (methodName.startsWith("get") && method.getParameters().length == 0) {
            /* Found the get method. */
            objectName = methodName.substring("get".length());

            GetterSetterPair getterSettingPair = getterSetterMapping.get(objectName);
            if (getterSettingPair == null) {
                getterSettingPair = new GetterSetterPair();
                getterSetterMapping.put(objectName, getterSettingPair);
            }
            getterSettingPair.setGetter(method);
        } else if (methodName.startsWith("set") && method.getParameters().length == 1) {
            /* Found the set method. */
            objectName = methodName.substring("set".length());

            GetterSetterPair getterSettingPair = getterSetterMapping.get(objectName);
            if (getterSettingPair == null) {
                getterSettingPair = new GetterSetterPair();
                getterSetterMapping.put(objectName, getterSettingPair);
            }
            getterSettingPair.setSetter(method);
        } else if (methodName.startsWith("is") && method.getParameters().length == 0) {
            /* Found the is method, which really is a get method. */
            objectName = methodName.substring("is".length());

            GetterSetterPair getterSettingPair = getterSetterMapping.get(objectName);
            if (getterSettingPair == null) {
                getterSettingPair = new GetterSetterPair();
                getterSetterMapping.put(objectName, getterSettingPair);
            }
            getterSettingPair.setGetter(method);
        }
    }

    /*
     * Found all our mappings. Now call the getter and setter or set the field via reflection and call the getting
     * it doesn't have a setter.
     */
    for (final Entry<String, GetterSetterPair> entry : getterSetterMapping.entrySet()) {
        final GetterSetterPair pair = entry.getValue();

        final String objectName = entry.getKey();
        final String fieldName = objectName.substring(0, 1).toLowerCase() + objectName.substring(1);

        if (pair.hasGetterAndSetter()) {
            /* Create an object. */
            final Class<?> parameterType = pair.getSetter().getParameterTypes()[0];
            final Object newObject = createObject(fieldName, parameterType);

            try {
                pair.getSetter().invoke(instance, newObject);
            } catch (Exception e) {
                continue;
            }

            callGetter(fieldName, pair.getGetter(), instance, newObject);
        } else if (pair.getGetter() != null) {
            /*
             * Object is immutable (no setter but Hibernate or something else sets it via reflection). Use
             * reflection to set object and verify that same object is returned when calling the getter.
             */
            final Object newObject = createObject(fieldName, pair.getGetter().getReturnType());
            Field field = null;
            try {
                field = instance.getClass().getDeclaredField(fieldName);
            } catch (Exception e) {
                continue;
            }
            field.setAccessible(true);
            field.set(instance, newObject);

            callGetter(fieldName, pair.getGetter(), instance, newObject);
        }
    }
    }

}

public class GetterSetterPair {
    /** The get method. */
    private Method getter;

    /** The set method. */
    private Method setter;

    /**
     * Returns the get method.
     *
     * @return The get method.
     */
    public Method getGetter() {
        return getter;
    }

    /**
     * Returns the set method.
     *
     * @return The set method.
     */
    public Method getSetter() {
        return setter;
    }

    /**
     * Returns if this has a getter and setting method set.
     *
     * @return If this has a getter and setting method set.
     */
    public boolean hasGetterAndSetter() {
        return this.getter != null && this.setter != null;
    }

    /**
     * Sets the get Method.
     *
     * @param getter The get Method.
     */
    public void setGetter(Method getter) {
        this.getter = getter;
    }

    /**
     * Sets the set Method.
     *
     * @param setter The set Method.
     */
    public void setSetter(Method setter) {
        this.setter = setter;
    }
}
}
公共抽象类EntityDtoTraverser{
/**通用对象的默认映射器的映射*/
私有静态最终不可变映射>默认映射器;
静止的{
final Builder>mapperBuilder=ImmutableMap.Builder();
/*原语*/
mapperBuilder.put(int.class,新供应商(){
@凌驾
公共对象get(){
返回0;
}
});
mapperBuilder.put(double.class,新供应商(){
@凌驾
公共对象get(){
返回0.0d;
}
});
mapperBuilder.put(float.class,新供应商(){
@凌驾
公共对象get(){
返回0.0f;
}
});
mapperBuilder.put(long.class,新供应商(){
@凌驾
公共对象get(){
返回0升;
}
});
mapperBuilder.put(boolean.class,新供应商(){
@凌驾
公共对象get(){
返回true;
}
});
mapperBuilder.put(short.class,new Supplier()){
@凌驾
公共对象get(){
返回(短)0;
}
});
mapperBuilder.put(byte.class,新供应商(){
@凌驾
公共对象get(){
返回(字节)0;
}
});
mapperBuilder.put(char.class,新供应商(){
@凌驾
公共对象get(){
返回(char)0;
}
});
mapperBuilder.put(Integer.class,新供应商(){
@凌驾
公共对象get(){
返回整数.valueOf(0);
}
});
mapperBuilder.put(Double.class,新供应商(){
@凌驾
公共对象get(){
返回Double.valueOf(0.0);
}
});
mapperBuilder.put(Float.class,新供应商(){
@凌驾
公共对象get(){
返回浮动。值为(0.0f);
}
});
mapperBuilder.put(Long.class,新供应商(){
@凌驾
公共对象get(){
返回Long.valueOf(0);
}
});
mapperBuilder.put(Boolean.class,新供应商(){
@凌驾
公共对象get(){
返回Boolean.TRUE;
}
});
mapperBuilder.put(Short.class,new Supplier()){
@凌驾
公共对象get(){
返回Short.valueOf((Short)0);
}
});
mapperBuilder.put(Byte.class,新供应商(){
@凌驾
公共对象get(){
返回Byte.valueOf((Byte)0);
}
});
mapperBuilder.put(Character.class,新供应商(){
@凌驾
公共对象get(){
返回字符.valueOf((char)0);
}
});
mapperBuilder.put(BigDecimal.class,新供应商(){
@凌驾
公共对象get(){
返回BigDecimal.1;
}
});
mapperBuilder.put(Date.class,新供应商(){
@凌驾
公共对象get(){
返回新日期();
}
});
/*集合类型*/
mapperBuilder.put(Set.class,新供应商(){
@凌驾
公共对象get(){
返回集合;
}
});
mapperBuilder.put(SortedSet.class,新供应商(){
@凌驾
公共对象get(){
返回集合。emptySortedSet();
}
});
mapperBuilder.put(List.class,新供应商(){
@凌驾
公共对象get(){
返回集合。emptyList();
}
});
mapperBuilder.put(Map.class,新供应商(){
@凌驾
公共对象get(){
return Collections.emptyMap();
}
});
mapperBuilder.put(SortedMap.class,新供应商(){
@凌驾
公共对象get(){
返回集合。emptySortedMap();
}
});
默认_MAPPERS=mapperBuilder.build();
}
/**get字段将被忽略,而不是尝试测试*/
专用最终设置ignoredGetFields;
/**
*自定义映射器。通常在测试类具有抽象对象时使用。
*/
私有最终ImmutableMap>mappers;
/**
*使用默认忽略字段创建{@link EntityDtoTraverser}的实例。
*/
受保护的EntityDtoTraverser(){
这个(空,空);
}
/**
*使用忽略字段和其他自定义映射器创建{@link EntityDtoTraverser}的实例。
*
*@param customMappers给定类类型的任何自定义映射器。
*@param ignoreFields应忽略的getter(例如,“getId”或“isActive”)。
*/
受保护的EntityDtoTraverser(映射>自定义映射器,设置ignoreFields){
this.ignoredGetFields=new HashSet();
if(ignoreFields!=null){
this.ignoredGetFields.addAll(ignoreFields);
}
this.ignoredGetFields.add(“getClass”);
if(customMappers==null){
this.mappers=默认映射器;
}否则{
final Builder>Builder=ImmutableMap.Builder();
builder.putAll(自定义映射程序);
builder.putAll(默认映射器);
this.mappers=builder.build();
}
}
/**
*调用getter并验证结果是否符合预期。
*
*@param fieldName字段名(用于错误消息)。
*@param getter获取{@link方法}。
*@param instance测试实例。
*@param期望得到预期的结果。
*
*如果此方法对象正在强制执行Java语言访问控制和底层
*方法无法访问。
*如果方法是实例方法且指定的对象参数不是实例,则@throws IllegalArgumentException
*声明底层方法(或子类或实现者)的类或接口的实例
*如果麻木
public class DtoTest extends EntityDtoTraverser<Object>{

private ArrayList<String> clazez = new ArrayList<String>();
private int index = 0;
private int folderIndex = 0;
private String[] folders = new String[]{"src"};

public void listFilesForFolder(File folder) {
    for (File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            listFilesForFolder(fileEntry);
        } else {
            String fileName=fileEntry.getPath();
            for(int i = 0;i<2;++i) {
                fileName = fileName.substring(fileName.indexOf("\\") + 1, fileName.length());
            }
            fileName = fileName.substring(fileName.indexOf("\\") + 1, fileName.length() - 5);
            fileName = fileName.replace('\\', '.');
            if(!fileName.contains("Service")){
                clazez.add(fileName);
            }
        }
    }
}

@Override
protected Object getInstance() {
    while(true) {
        try {
            if (index >= clazez.size() || clazez.isEmpty()) {
                if(folderIndex >= folders.length) {
                    return null;
                }
                index = 0;
                clazez = new ArrayList<String>();
                testFolder(folders[folderIndex]);
                folderIndex++;
            }
            Class<?> c = Class.forName(clazez.get(index));
            index++;
            return (Object) c.newInstance();
        }catch (ClassNotFoundException e) {
            index++;
        } catch (IllegalAccessException e) {
            index++;
        } catch (InstantiationException e) {
            index++;
        }
    }
}

private void testFolder(String folderName) {
    File folder = new File(folderName);
    listFilesForFolder(folder);
}
}