在我的DoFo的unittest中,是否可以通过比较记录的序列化表示来断言输出与预期输出匹配?
我已经定义了一个使用默认avro编码器的记录,例如
@DefaultCoder(AvroCoder.class)
public class JobLogMessage {
@Nullable
public String projectId;
...
}
我正在为一个使用DoFnTester生成JobLogMessage列表的DoFn编写单元测试,例如。
JogLogTransforms.ParsJsonDoFn doFn = new JogLogTransforms.ParsJsonDoFn();
DoFnTester<String, JobLogMessage> fnTester = DoFnTester.of(doFn);
List<JobLogMessage> outputs = fnTester.processBatch(inputs.toArray(new String[inputs.size()]));
我想验证输出是否符合预期输出。但是,如果我只使用assertEquals,我认为将使用equals方法,该方法无法正确评估相等性,除非我在JobLogMessage中显式地重载equals。
我想要做的是通过比较AvroCoder生成的序列化字节表示来比较预期和实际的JobLogMessage。 Dataflow是否为此提供了任何便利方法?
答案 0 :(得分:1)
如果您对需要确定性模式的限制没有问题,可以稍微简化一下代码,以便更好地利用SDK和JDK中提供的实用程序。
public boolean equals(Object obj) {
if (!(obj instanceof JobLogMessage)) {
return false;
}
JobLogMessage other = (JobLogMessage) obj;
AvroCoder<JobLogMessage> coder = AvroCoder.of(JobLogMessage.class);
return Arrays.equals(CoderUtils.encodeToByteArray(this, coder),
CoderUtils.encodeToByteArray(obj, coder));
}
那就是说,我认为使用来自apache commons-lang的EqualsBuilder和HashCodeBuilder之类的东西会更好,这些内容是为你的目标明确设计的(编码器不是旨在用作哈希和平等测试者) - 只需使用return EqualsBuilder.reflectionEquals(this, obj)
。
答案 1 :(得分:0)
我使用AvroCoder实现equals生成序列化表示,然后比较序列化表示。
@Override
public boolean equals(Object obj) {
if (!(obj instanceof JobLogMessage)) {
return false;
}
JobLogMessage other = (JobLogMessage) obj;
AvroCoder<JobLogMessage> coder = AvroCoder.of(JobLogMessage.class);
Coder.Context context = new Coder.Context(true);
ByteArrayOutputStream thisStream = new ByteArrayOutputStream();
try {
coder.encode(this, thisStream, context);
} catch (IOException e) {
throw new RuntimeException("There was a problem encoding the object.", e);
}
ByteArrayOutputStream otherStream = new ByteArrayOutputStream();
try {
coder.encode(other, otherStream, context);
} catch (IOException e) {
throw new RuntimeException("There was a problem encoding the object.", e);
}
byte[] theseBytes = thisStream.toByteArray();
byte[] otherBytes = otherStream.toByteArray();
if (theseBytes.length != otherBytes.length) {
return false;
}
for (int i = 0; i < theseBytes.length; ++i) {
if (theseBytes[i] != otherBytes[i]) {
return false;
}
}
return true;
}