proposal: use a better printer/differencer for failed matches #265
Comments
Very good idea! For now, it's hard to tell where a struct differs. It's even worse when the struct is deep and has nested structs. Regarding diff outputing: Testify has human readable diffs; but go-testdeep goes a step beyond with colors! |
https://github.com/golang/mock#modifying-failure-messages I think covers this. @Capstan Thoughts? |
well @codyoss not completely.
|
I think this is less of a problem with some more recent changes: #559 and #236. |
Closing this issue as resolved, see above comment. |
I think two big pain points were missed here:
#236 makes it so we can control formatting of specific values/matchers on a per-assertion basis, which sort of fixes the first point, but not really. I don't know about you, but I don't particularly want to go wrap all the values in all the expectations in all my codebase's tests just so I can tell what's actually breaking. If I absolutely had to, I'd wind up writing a handful of utilities that would basically look like the following, then put it absolutely everywhere: func fmteq(v interface{}) gomock.Matcher {
return gomock.WantFormatter(
gomock.StringerFunc(func() string {
return prettyprint(v)
}),
gomock.GotFormatterAdapter(
gomock.GotFormatterFunc(prettyprint),
gomock.Eq(v),
),
)
} All in all, not great. It would be cool to be able to insert a default formatter somehow, maybe on the controller or through a global var in the package. If there's a way to do this already, it's not clear from the current documentation. As to the second issue, as far as I know, there's no mechanism at all that would let you do a diff of the two values. As noted by @maelvls, As it stands, I'm looking at this mess trying to figure out what about it isn't equal:
(yes, I know it's the Sure, I can drop spew or similar in here for cases like this, but a) doing that by default means I need to get approval for the new dependency from legal, and b) doing that on-off means I need to waste a ton of time adding the dependency to bazel for a one-off test. It'd be so much easier if gomock just defaulted to human-friendly output. |
Thanks for the thoughtful comment @austinhyde. I still think the original issue was addressed here, but we can alway strive to be better. Would you mind summarizing your thoughts in a new issue and provide a small code example the demonstrates how/why this would be useful. |
Honestly, I don't believe the original issue was addressed in any meaningful way:
OP provided a possible route to providing these features. If you don't like that approach for whatever reason, that's one thing, but that doesn't invalidate the overall ask. You asked for examples where the linked issues are not sufficient, except that neither issue actually addresses any of the OP's asks. You ask me to provide a code example of why this would be useful - that's exactly what I posted. It's not readable for any sane definition of the word. Do you want me to actually write up a full test case that just... outputs the exact same thing? How is that at all a good use of my time to write it or yours to read it? The issue is around the default formatting of the library's output, the usefulness of such a feature should be apparent in the output, not the code that generates that output. Literally any |
There's a workaround using the current gomock API (as of v1.6.0): #616 (comment) |
I agree with @austinhyde, the issue is not addressed. gomock is great but its output is not great at helping you iterate faster due to the cryptic messages when it fails at trying to match structs. |
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.,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
forGot
, and matchers'sString
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
orMatchAndExplain
to be able to more thoroughly specify what happened. To preserve backwards incompatibility, this would be in a new interface, e.g.,Then, in lieu of using
Matcher.String
and explicit Got/Want errors incall.go
, rely onMatchAndExplain
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.The text was updated successfully, but these errors were encountered: