我可以比较单元测试中记录的序列化表示形式吗



在我的DoFo的单元测试中,是否可以通过比较记录的序列化表示来断言输出与预期输出匹配?

我定义了一个使用默认avro编码器的记录,例如

@DefaultCoder(AvroCoder.class)
public class JobLogMessage {
  @Nullable
  public String projectId;
  ...
}

我正在为DoFn编写一个单元测试,它使用DoFnTester生成JobLogMessage的列表,例如

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,否则该方法不会正确计算equals。

我想做的是通过比较AvroCoder生成的序列化字节表示来比较预期的和实际的JobLogMessage。Dataflow对此有任何方便的方法吗?

如果您同意需要确定性模式的限制,您可以在一定程度上简化代码,以更好地利用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));
}

也就是说,我认为使用apachecommons-lang中的EqualsBuilder和HashCodeBuilder这样的东西要好得多,它们是为您的目标明确设计的(编码器不是为用作哈希器和平等测试程序而设计的)-只需使用return EqualsBuilder.reflectionEquals(this, obj)

我使用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;
  }

最新更新