如何使用不变检查对序列化进行单元测试?

时间:2014-03-09 21:01:18

标签: java unit-testing serialization

我有一个带有不变检查的不可变类。根据Effective Java 2nd Ed项目76,它有一个readObjects方法,如果反序列化的对象违反了不变量,则抛出InvalidObjectException:

// readObject method with validity checking
private void readObject(ObjectInputStream s)
        throws IOException, ClassNotFoundException {
    s.defaultReadObject();

    // Check that our invariants are satisfied
    if (/* some condition*/)
        throw new InvalidObjectException("Invariant violated");
}

我知道如何test serialization and deserialization,但这只测试了快乐的道路。有一种丑陋的触发InvalidObjectException的方法,你在那里硬编码一个被篡改的字节流(从EJ2 item 76无耻地被盗):

public class BogusPeriod {
    // manipulated byte stream
    private static final byte[] serializedForm = new byte[] {
        (byte)0xac, (byte)0xed, 0x00, 0x05, /* ca. 100 more bytes omitted */ };

    // Returns the object with the specified serialized form
    private static Object deserializeBogusPeriod() {
        try {
            InputStream is = new ByteArrayInputStream(serializedForm);
            ObjectInputStream ois = new ObjectInputStream(is);
            return ois.readObject();
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }
}

这非常难看,并且一旦可序列化类发生变化就可能会破坏。 我想知道是否有更简单的方法来创建这样的测试用例?也许有一个库知道字节流特定值的哪些偏移位于运行时允许篡改?

1 个答案:

答案 0 :(得分:1)

您假设,对象/类可以从java反序列化(非损坏数据),并且希望之后进行一些检查(例如,如果字符串中的日期格式正确)。

为此编写单元测试,您可以使用像Serialysis(https://weblogs.java.net/blog/2007/06/12/disassembling-serialized-java-objects)这样的库来检查合法的流对象生成的字节流,找出数据所在的字节流中的位置并在此期间修改数据测试设置。

虽然

IF 您信任您收到的数据源并且能够反序列化,更好地使用您选择的框架提供的某种拦截器/验证器(Spring in SE,Java EE等。 )当对象到达你的应用程序时。