-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Mockito-ArgumentMatchers-parameterized-call.ql
- Loading branch information
1 parent
f79c5ca
commit 4f0ccff
Showing
1 changed file
with
45 additions
and
0 deletions.
There are no files selected for viewing
45 changes: 45 additions & 0 deletions
45
codeql-custom-queries-java/queries/unit-tests/Mockito-ArgumentMatchers-parameterized-call.ql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* Finds usage of Mockito's `ArgumentMatchers` methods where type arguments | ||
* are explicitly provided. If the type arguments are not constrained by | ||
* a method argument (e.g. `Class<T>`) they have no effect at runtime and | ||
* can be confusing, giving the false expression that Mockito will only | ||
* match the specified types. | ||
* | ||
* Instead the type arguments should be omitted; the compiler will then | ||
* infer them. | ||
* | ||
* For example: | ||
* ```java | ||
* // Error-prone: Looks as if this only matches String, but it actually | ||
* // matches anything | ||
* // Should instead just use `Mockito.any()`, or `Mockito.anyString()` | ||
* verify(myObj).doSomething(Mockito.<String>any()); | ||
* ``` | ||
* | ||
* @kind problem | ||
* @id TODO | ||
*/ | ||
|
||
import java | ||
|
||
from MethodAccess matcherCall, Method matcherMethod, Expr typeArg | ||
where | ||
matcherCall.getMethod().getSourceDeclaration() = matcherMethod and | ||
matcherMethod.getDeclaringType().hasQualifiedName("org.mockito", "ArgumentMatchers") and | ||
// There is no method parameter which could restrict the type argument (e.g. `Class<T>`) | ||
matcherMethod.hasNoParameters() and | ||
// Explicitly specifies type arguments, instead of letting the compiler infer them | ||
typeArg = matcherCall.getATypeArgument() and | ||
// Ignore if type arguments are needed to select the correct overload | ||
not exists(MethodAccess stubbedCall, Method stubbedMethod, int argIndex, SrcMethod overload | | ||
stubbedCall.getMethod().getSourceDeclaration() = stubbedMethod and | ||
stubbedCall.getArgument(argIndex) = matcherCall and | ||
overload.getDeclaringType() = | ||
stubbedCall.getReceiverType().getSourceDeclaration().getASourceSupertype*() and | ||
overload.getName() = stubbedMethod.getName() and | ||
overload.getNumberOfParameters() = stubbedMethod.getNumberOfParameters() and | ||
overload.getParameterType(argIndex) != stubbedMethod.getParameterType(argIndex) and | ||
overload != stubbedMethod and | ||
not overload.isPrivate() | ||
) | ||
select typeArg, "Explicit type argument should be omitted because it can be misleading" |