0

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

我已经定义了一个使用默认 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,我认为除非我在 JobLogMessage 中显式重载 equals,否则它将使用不会正确评估相等性的 equals 方法。

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

4

2 回答 2

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 中的EqualsBuilderHashCodeBuilder之类的东西要好得多,它们是为您的目标明确设计的(编码器不是为用作哈希器和相等测试器而设计的)——只需使用return EqualsBuilder.reflectionEquals(this, obj).

于 2015-03-30T15:31:11.563 回答
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;
  }
于 2015-03-29T21:50:05.333 回答