我有一个带有不变检查的不可变类。根据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);
}
}
}
这非常难看,并且一旦可序列化类发生变化就可能会破坏。 我想知道是否有更简单的方法来创建这样的测试用例?也许有一个库知道字节流特定值的哪些偏移位于运行时允许篡改?
答案 0 :(得分:1)
您假设,对象/类可以从java反序列化(非损坏数据),并且希望之后进行一些检查(例如,如果字符串中的日期格式正确)。
为此编写单元测试,您可以使用像Serialysis(https://weblogs.java.net/blog/2007/06/12/disassembling-serialized-java-objects)这样的库来检查合法的流对象生成的字节流,找出数据所在的字节流中的位置并在此期间修改数据测试设置。
虽然
IF 您信任您收到的数据源并且能够反序列化,更好地使用您选择的框架提供的某种拦截器/验证器(Spring in SE,Java EE等。 )当对象到达你的应用程序时。