Skip to content

Conversation

brackendawson
Copy link
Collaborator

@brackendawson brackendawson commented Jun 29, 2022

Summary

Passing an actual value of type nil via a Mock into the argument matcher for AnythingOfType in a Mock causes a panic.

Changes

  • Handle nil types up front when checking actual types against mock.AnythingOfType before calling any methods on the reflect.Type, which will be nil if the value was a nil interface.
  • Change formatting of the expected type from Name() to String() because Name is emptystring for pointer and some other types.

Motivation

Someone may expect their mock to be called with a nil interface, we should not panic in this case.

Related issues

Closes #1209

Handle nil types up front before calling any methods on the reflect.Type

}

func Test_Arguments_Diff__WithAnythingOfTypeArgument_NilType(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have an extra underscore here, please look at test names above to maintain consistency :)


}

func Test_Arguments_Diff__WithAnythingOfTypeArgument_NilType_Failing(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment on line 1616

differences++
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type <nil> - %s\n", output, i, expected, actualFmt)
}
} else if reflect.TypeOf(actual).Name() != string(expected.(AnythingOfTypeArgument)) && reflect.TypeOf(actual).String() != string(expected.(AnythingOfTypeArgument)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the String() function documentation:

	// String returns a string representation of the type.
	// The string representation may use shortened package names
	// (e.g., base64 instead of "encoding/base64") and is not
	// guaranteed to be unique among types. To test for type identity,
	// compare the Types directly.

we should not be using it for comparison.

Do you mind updating and fixing the logic to reflect this?

Copy link
Collaborator Author

@brackendawson brackendawson Jun 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely agree we should not be using String() for that comparison. The original author seems to have used both Name() and String() to work around the non-defined types thing on Name().

I'm struggling to find an alternative though, the ideal would be to follow the advice in the docs and compare the reflect.Type values directly, but this would be a breaking change because right now people write expectations like mock.AnythingOfType("*string") and we'd need them to pass in at least a literal instead, which might not even be possible for foreign unexported types.

reflect doesn't offer an easy way of doing it (some experimentation here). I think it could maybe be done but we'd need to:

  1. Dereference pointer types and prepend a * ourselves.
  2. Join the value returned by PkgPath() and Name() on the dereferenced value with a /, (this might also be considered a breaking change as types would become fully qualified).
  3. Figure out if there are any other "non-defined" types and work out how to get their name as a string.

Do you think it's worth trying in this PR? I'm leaning towards open an issue to fix it in testify v2 by changing:

func AnythingOfType(t string) AnythingOfTypeArgument

to:

func AnythingOfType(t any) argumentMatcher

and do away with AnythingOfTypeArgument altogether.

@greenstatic
Copy link

I ran into this issue as well. Is there any activity on this PR fixing this issue?

@brackendawson
Copy link
Collaborator Author

I ran into this issue as well. Is there any activity on this PR fixing this issue?

I believe the state is that fixing this well would be a breaking change, so not until Testify 2.0, and I think we should do that. But the comments above object to something which is not a regression, so I think this change can be merged into 1.x.

@dolmen dolmen added pkg-mock Any issues related to Mock mock.ArgumentMatcher About matching arguments in mock labels Mar 7, 2024
@brackendawson
Copy link
Collaborator Author

#1799 is a better approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mock.ArgumentMatcher About matching arguments in mock pkg-mock Any issues related to Mock

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mock panics when argument of nil type checked against AnythingOfType

4 participants