Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve vararg handling #2805

Closed
wants to merge 4 commits into from
Closed

Conversation

big-andy-coates
Copy link
Contributor

@big-andy-coates big-andy-coates commented Nov 28, 2022

Fixes: #2796

An alternative approach is available in #2807.

Add an optional method to VarargMatcher, which implementations can choose to override to return the type of object the matcher is matching.

This is used by MatcherApplicationStrategy to determine if the type of matcher used to match a vararg parameter is of a type compatible with the vararg parameter.

Where a vararg compatible matcher is found, the matcher is used to match the raw parameters.

Known limitations

The main limitation I'm aware of, is not a new limitation. It is that it is not possible to assert only a single parameter is passed to the vararg parameter, when using a VarargMatcher. (ref: #1593). For example:

// Given method:
int vararg(String... args);

// I want to mock this invocation:
mock.vararag("one param");

// ...but not these:
mock.vararg();
mock.vararg("more than", "one param");

There is no current way to do this. This is because in the following intuitive mocking:

given(mock.vararg(any(String.class))).willReturn(1);

... matches zero or more vararg parameters, as the any() method is using VarargMatcher.

It seems to me that VarargMatcher is... a little broken. This PR leverages VarargMatcher... which, if its broken, might not be something we want to do.

Checklist

  • Read the contributing guide
  • PR should be motivated, i.e. what does it fix, why, and if relevant how
  • If possible / relevant include an example in the description, that could help all readers
    including project members to get a better picture of the change
  • Avoid other runtime dependencies
  • Meaningful commit history ; intention is important please rebase your commit history so that each
    commit is meaningful and help the people that will explore a change in 2 years
  • The pull request follows coding style
  • Mention Fixes #<issue number> in the description if relevant
  • At least one commit should mention Fixes #<issue number> if relevant

Fixes: mockito#2796

Add an optional method to `VarargMatcher`, which implementations
can choose to override to return the type of object the matcher is matching.

This is used by `MatcherApplicationStrategy` to determine if the type of matcher used to match a vararg parameter is of a type compatible with the vararg parameter.

Where a vararg compatible matcher is found, the matcher is used to match the _raw_ parameters.
@big-andy-coates
Copy link
Contributor Author

@TimvdLippe here's one possible solution. Please take a look when you get time. However, please don't merge if you're happy just yet, as I'd like to try out another possible solution. One that removes the need for VarargMatcher all together....

@codecov-commenter
Copy link

codecov-commenter commented Nov 28, 2022

Codecov Report

Base: 86.18% // Head: 86.19% // Increases project coverage by +0.00% 🎉

Coverage data is based on head (b2b8122) compared to base (8f4af18).
Patch coverage: 92.30% of modified lines in pull request are covered.

❗ Current head b2b8122 differs from pull request most recent head 87dbe8c. Consider uploading reports for the commit 87dbe8c to get more accurate results

Additional details and impacted files
@@            Coverage Diff            @@
##               main    #2805   +/-   ##
=========================================
  Coverage     86.18%   86.19%           
- Complexity     2833     2839    +6     
=========================================
  Files           320      321    +1     
  Lines          8586     8605   +19     
  Branches       1060     1064    +4     
=========================================
+ Hits           7400     7417   +17     
- Misses          905      906    +1     
- Partials        281      282    +1     
Impacted Files Coverage Δ
...ito/internal/hamcrest/HamcrestArgumentMatcher.java 85.71% <0.00%> (-14.29%) ⬇️
...a/org/mockito/internal/matchers/VarargMatcher.java 0.00% <0.00%> (ø)
src/main/java/org/mockito/ArgumentCaptor.java 100.00% <100.00%> (ø)
...nternal/invocation/MatcherApplicationStrategy.java 100.00% <100.00%> (ø)
...c/main/java/org/mockito/internal/matchers/Any.java 100.00% <100.00%> (ø)
...rg/mockito/internal/matchers/CapturingMatcher.java 100.00% <100.00%> (ø)
...java/org/mockito/internal/matchers/InstanceOf.java 100.00% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@big-andy-coates big-andy-coates mentioned this pull request Nov 28, 2022
8 tasks
@big-andy-coates
Copy link
Contributor Author

@TimvdLippe alternative approach raised in #2807.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Mocking varargs method with any(String[].class) doesn't work as expected
2 participants