java项目中所有类的单元测试可序列化性

Ros*_*Ros 5 java serialization unit-testing

我的 java 项目中有数千个类。其中一些实现了可序列化接口。现在有一个问题。有人可能可以进入一个类,添加既不是瞬态也不是可序列化的新变量。代码编译得很好,但进程会在运行时崩溃。

为了说明这一点

class Foo implements Serializable {  .... // all good }

class Foo implements Serializable 
{  
    // OOps, executorService is not serializable.  It's not declared as transient either 

    private ExecutorService executorService = ..
}
Run Code Online (Sandbox Code Playgroud)

我正在考虑编写一个单元测试来遍历所有类并确保“真正的可串行化”。我读过一些有关序列化特定对象的讨论。我理解这个过程,但它需要

1)创建一个对象。
2)序列化,然后
3)反序列化。

有没有更高效、实用的方法。也许要使用反射。遍历所有类,如果类具有可序列化,则所有属性都必须可序列化或具有瞬态关键字。

想法?

Rya*_*art 1

如果序列化是应用程序的关键部分,那么请将序列化包含在测试中。就像是:

@Test
public void aFooSerializesAndDeserializesCorrectly {
    Foo fooBeforeSerialization = new Foo();
    ReflectionUtils.randomlyPopulateFields(foo);
    Foo fooAfterSerialization = Serializer.serializeAndDeserialize(foo);
    assertThat(fooAfterSerialization, hasSameFieldValues(fooBeforeSerialization));
}
Run Code Online (Sandbox Code Playgroud)

编辑:一个简单的实现randomlyPopulateFields

public static void randomlyPopulateFields(final Object o) {
    ReflectionUtils.doWithFields(o.getClass(), new ReflectionUtils.FieldCallback() {
        public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
            ReflectionUtils.makeAccessible(field);
            ReflectionUtils.setField(field, o, randomValueFor(field.getType()));
        }

        private Random r = new Random();
        private Object randomValueFor(Class<?> type) {
            if (type == String.class) {
                return String.valueOf(r.nextDouble());
            } else if (type == Boolean.class || type == Boolean.TYPE) {
                return r.nextBoolean();
            } else if (type == Byte.class || type == Byte.TYPE) {
                return (byte) r.nextInt();
            } else if (type == Short.class || type == Short.TYPE) {
                return (short) r.nextInt();
            } else if (type == Integer.class || type == Integer.TYPE) {
                return r.nextInt();
            } else if (type == Long.class || type == Long.TYPE) {
                return (long) r.nextInt();
            } else if (Number.class.isAssignableFrom(type) || type.isPrimitive()) {
                return Byte.valueOf("1234");
            } else if (Date.class.isAssignableFrom(type)) {
                return new Date(r.nextLong());
            } else {
                System.out.println("Sorry, I don't know how to generate values of type " + type);
                return null;
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)