Protobuf Extension

ProtoTruth is an extension of the Truth library which lets you make assertions about Protobufs, a rich data interchange format. To get started:

  1. Add the appropriate dependency to your build:

    Maven:

    <dependency>
      <groupId>com.google.truth.extensions</groupId>
      <artifactId>truth-proto-extension</artifactId>
      <version>0.31</version>
    </dependency>
    

    Gradle:

    buildscript {
      repositories.mavenLocal()
    }
    dependencies {
      testCompile "com.google.truth.extensions:truth-proto-extension:0.31"
    }
    

    Use truth-liteproto-extension if you are using the lite version of Protobufs. Note that this extension lacks many of the features in the full extension due to the lack of runtime descriptors. You’ll also need to import LiteProtoTruth instead of ProtoTruth.

  2. Add a static import:

    import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
    

    NOTE: ProtoTruth.assertThat and Truth.assertThat can both be statically imported in the same file. Java handles overloaded static imports much like overloads defined in the same class.

  3. Assert away!

    MyProto expected = MyProto.newBuilder().addBar(3).addBar(5).setFoo(qux).build();
    MyProto actual =   MyProto.newBuilder().addBar(5).addBar(3).setFoo(quizzux).build();
    assertThat(actual).ignoringRepeatedFieldOrder().isEqualTo(expected);
    

    This assertion yields the following failure message:

    Not true that messages compare equal.  Differences were found:
    modified: foo: ”qux” -> “quizzux”
    

Supported Use Cases

Support exists for:

Support does not currently exist (yet) for:

Support will not exist for:

Strict default behavior

By default, the extension is fairly strict and requires you to explicitly state your test assumptions. It will:

In summary, the default isEqualTo() behavior of ProtoSubject is behaviorally identical to Subject behavior. However, you will get much better error messaging in the event of a failure.

Getting better failure messages by enabling pairing of Iterable elements

When an assertion involving an Iterable of protos fails, the failure messages can often be hard to understand. If you know of some key function which uniquely indexes the expected protos, you can use the displayingDiffsPairedBy method to tell ProtoTruth about it. For example, if you have a proto called Record, and you’re making an assertion about an Iterable<Record>, and the expected records have unique values of an id field, then you could write this:

assertThat(actualRecordProtos)
    .displayingDiffsPairedBy(Record::getId)
    .containsExactlyElementsIn(expectedRecords);

If this assertion fails, the failure message will pair up any missing and unexpected elements by their IDs. For example, it might tell you that the actual Iterable was missing an element with ID 2, that it had an unexpected element with ID 3, or that the element with ID 4 wasn’t equivalent to the one it expected… and in this last case, it will also show a field-by-field diff between the proto it got and the one it expected.

(If an assertion about a Map fails, the failure message will automatically match up any missing and unexpected entries using their keys. You can think of the displayingDiffsPairedBy method as providing an equivalent for an assertion about an Iterable. Note that this won’t affect whether the test passes or fails.)