Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

proposal: use a better printer/differencer for failed matches #265

Closed
@Capstan

Description

@Capstan

See also issue #233 which is related.

When a gomock call fails an expectation, if the argument is an interface, the output, based on the %v format character, is not terribly helpful, e.g.,

   controller.go:150: Unexpected call to *jobs_mock.MockJobs.Insert([testproject 0xc0001f2420]) at …/jobs_mock.go:62 because: 
        Expected call at …/my_test.go:132 doesn't match the argument at index 1.
        Got: &{0xc000206300   0xc00020c120   <nil> <nil>  {0 map[]} [] []}
        Want: is equal to &{0xc000206100   0xc0000f5020   <nil> <nil>  {0 map[]} [] []}

This doesn't help isolate the problem, which is only visible to reflect.DeepEqual and is not obvious to me, the viewer of the test results. (The problem from the above turned out to be two levels deep into an embedded struct.)

Please consider either or both of the following:

Pretty-print the values

This would involve changing the code in calls.go to use a formatter other than %v for Got, and matchers's String implementation to use the same on the embedded interface. e.g.,

Print a diff of the values

This would involve adding a new Matcher method, e.g., Explain or MatchAndExplain to be able to more thoroughly specify what happened. To preserve backwards incompatibility, this would be in a new interface, e.g.,

type Explainer interface {
  // MatchAndExplain returns whether x is a match and why.
  MatchAndExplain(x interface{}) (bool, string)
}

func (e eqMatcher) MatchAndExplain(x interface{}) (bool, string) {
  negation := ""
  diff := ""
  match := e.Matches(x)
  if !match {
    negate = "not "
    diff = fmt.Sprintf("\nGot: %v\nWant: %v\nDiff: %s", x, e.x, cmp.Diff(e.x, x))
  }
  return match, fmt.Sprintf("is %sequal to %v%s", negation, e.x, diff)
}

Then, in lieu of using Matcher.String and explicit Got/Want errors in call.go, rely on MatchAndExplain to yield the deep difference.


I'm not familiar with a go built-in pretty printer, so I think either of these would require either extending a core library, or allowing an import to do pretty printing / diffing. Not sure how feasible that is.

This approach is modeled at least partly after the C++ Google Test Matchers's MatcherInterface; many examples of implementations of which are in the Google Mock matchers.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions