Skip to content

Expand and externalize our docs on writing your own Subject #208

Description

@cpovirk

We have some docs internally. Other things for us to cover:

  • Don't throw AssertionError directly: Call this.fail():
    • fail() generates the appropriate type of failure (e.g., AssumptionViolatedException when someone uses assume().
    • fail() uses the user's failure message and subject name.
    • fail() has message to disambiguate objects with the same toString() but different classes.
    • fail() comes in overloads that help you construct the message.
  • Similarly, don't delegate sub-object assertions to assertThat(...): Delegate to check().that(...). (But note bug Do calls to Subject.check() lose the failureMessage? #199.) This preserves the failureStrategy.
  • Once you call fail(), don't do anything else. If someone is using expect() (or some custom FailureStrategy that logs failures -- I think Google has at least one), fail() won't throw, so execution will continue.
    • This could result in multiple separate failure reports ("size is different," "missing element a," "missing element b"). (Sometimes that could be a good thing, but if it's a good thing, then we should do it for assert(), too, by putting everything in one fail() call!)
    • Worse, it could result in exceptions: If we fail() if the sizes of two collections differ but then continue to iterate over them in parallel, we're likely to throw NoSuchElementException. This defeats the purpose of expect() and might(?) obscure the real error.
    • We could maybe "solve" the former problem by wrapping the FailureStrategy in some kind of failOnlyTheFirstTimeStrategy, but this doesn't help with the second problem.
    • Related question: What happens with expect() and chained assertions like containsExactly().inOrder()? I guess that we need to return the "inOrder() always succeeds" object, which we should maybe stop calling IN_ORDER and documenting as though it means that. It's possible that the failOnlyTheFirstTimeStrategy approach could be useful here, but I'm wary of it.
  • Distinguish between "check failed" and "bug in your test: check is bogus" (issue Policy describing the difference between "check failed" and "could not evaluate check" #207).
  • Use failComparing() when substring/subsequence matches are helpful to highlight.
  • [If we ever require you to override named() (issue Consider removing self type <S> from Subject #202), we should document that.]

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3not scheduledtype=documentationDocumentation that is other than for an API

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions