-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Add ArgumentMatchers#assertArg
method.
#2949
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simple and elegant, nice! I wonder if we can even deprecate ArgumentCaptor
at this point in favor of this, but let's cross that bridge when we get to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah in fact, it is good to call out this new API in our main documentation. To do so, add section 55 to
mockito/src/main/java/org/mockito/Mockito.java
Line 1663 in 0b8685c
* </p> |
* <a href="#54">54. Mocking/spying without specifying class (Since 4.9.0)</a><br/> |
It's best to include an example usage (such as the one you included in your PR description).
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #2949 +/- ##
============================================
+ Coverage 85.70% 85.75% +0.04%
- Complexity 2865 2872 +7
============================================
Files 325 325
Lines 8696 8716 +20
Branches 1074 1076 +2
============================================
+ Hits 7453 7474 +21
Misses 966 966
+ Partials 277 276 -1
... and 1 file with indirect coverage changes 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 in Codecov by Sentry. |
@TimvdLippe Javadocs added (feel free to rephrase if you find better wording). I added "(Since 5.3.0)" but I am not sure in which version exactly it would be released. |
Oops I didn't mean to approve! I was just really looking forward for this change and clicked the wrong button!. |
@TimvdLippe checkstyle issues are fixed now. Please take another look when you have a minute |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome thank you!
Even if this new feature is great and more elegant than We have some use cases where this will be hard to replace :
|
@sbernard31 I agree. An example when |
@sbernard31 @maciejwalkowiak I understand that use case and I think you can achieve the same with AtomicReference<String> reference = new AtomicReference<>();
verify(mock).invocation(assertArg(arg -> reference.set(arg)));
verify(mock).secondInvocation(eq(reference.get())); Hence I am not sure if we need a dedicate |
@TimvdLippe you're right about it seems we can do the same with But If we compare // assertArg + AtomicReference
AtomicReference<String> reference = new AtomicReference<>();
verify(mock).invocation(assertArg(arg -> reference.set(arg)));
verify(mock).secondInvocation(eq(reference.get()));
// ArgumentCaptor
ArgumentCaptor<String> arg = new ArgumentCaptor<>();
verify(mock).invocation(arg.capture());
verify(mock).secondInvocation(eq(arg.getValue())); |
@sbernard31 Right, that's exactly what we should be monitoring in the years to come, which pattern is used more frequently than the other. For now, there is no need to deprecate it, I only saw the similarities between the two API's and hence my comment, but nothing more than that. |
Will this work in kotlin too? Tried it just now and the arg is null.
Above code results to
|
In a couple of places, `argThat` was being called with a sequence of boolean expressions. That pattern of use is incorrect, and while all the expressions are evaluated only the last line of the block is returned and used by `argThat`. Any of the preceding expressions could evaluate to false without failing the test. The most direct fix to this would be to take the conjunction of all the expressions by interspersing some `&&` between each. While that would work, it would also lead to terribly obscure error message on a failure, as it would be impossible to figure out which expression evaluated to false. The chosen fix is to instead use a series of assertions, and then return true at the end of the block. Given that any failed assertion raises an exception, this doesn't have the same issue as the old code. It would have been nice to avoid the confusing `true` at the end. In fact, Mockito has added a [new `assertArg` method][assertArg] in recent versions. I tried to update mockito but ran into too many issues to deal with. [assertArg]: mockito/mockito#2949
In a couple of places, `argThat` was being called with a sequence of boolean expressions. That pattern of use is incorrect, and while all the expressions are evaluated only the last line of the block is returned and used by `argThat`. Any of the preceding expressions could evaluate to false without failing the test. The most direct fix to this would be to take the conjunction of all the expressions by interspersing some `&&` between each. While that would work, it would also lead to terribly obscure error message on a failure, as it would be impossible to figure out which expression evaluated to false. The chosen fix is to instead use a series of assertions, and then return true at the end of the block. Given that any failed assertion raises an exception, this doesn't have the same issue as the old code. It would have been nice to avoid the confusing `true` at the end. In fact, Mockito has added a [new `assertArg` method][assertArg] in recent versions. I tried to update mockito but ran into too many issues to deal with. [assertArg]: mockito/mockito#2949
Fixes #2285
Enables convenient alternative to
ArgumentCaptor
to assert arguments during verification:Verification succeeds as long as no exception is thrown from the lambda passed to
assertArg
, which means it works with any assertions (JUnit, AssertJ, ...).Since this is my first PR to Mockito, I may have missed something, or perhaps the documentation should be improved. Feedback is very welcome!
Checklist
including project members to get a better picture of the change
commit is meaningful and help the people that will explore a change in 2 years
Fixes #<issue number>
in the description if relevantFixes #<issue number>
if relevant