You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using the new `type()`, we can differentiate between matching all varargs
or only one argument of the varargs.
# Benefits:
Because this approach leaves `VarargsMatcher` untouched, it does not require additional existing matchers to implement `VarargsMatcher` to fix issues such as #567. Where as the first PR would require `Null` and `NotNull` to be marked `VarargsMatcher`.
This PR creates new variants of `isNotNull` and `isNull` to address #567.
Having `InstanceOf` override `type()` provides a workable solution to #1593.
Having `equals` override `type` addresses #1222.
# Downsides
The obvious downside is that this changes the public `ArgumentMatcher` interface, though in a backwards compatible way.
## Known limitation
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`, e.g. `any()`. (ref: #1593). For example:
```java
// 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:
```java
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 is maybe something that should be consider a candiate for fixing in the next major version bump.
While it is not possible to fix any `VarargMatcher` based matchers in a backwards compatible way, this the approach in this PR it is possible to mock/verify exactly one vararg param using `isA`, rather than `any`:
```java
@test
public void shouldMatchExactlyOnParam() {
mock.varargs("one param");
verify(mock).varargs(isA(String.class));
}
@test
public void shouldNotMatchMoreParams() {
mock.varargs("two", "params");
verify(mock, never()).varargs(isA(String.class));
}
@test
public void shouldMatchAnyNumberOfParams() {
mock.varargs("two", "params");
verify(mock).varargs(isA(String[].class));
}
```
... because `isA` does not implement `VarargsMatcher`, and so can work as expected once it implements `type()`.
Fixes#2796Fixes#567Fixes#584Fixes#1222Fixes#1498
0 commit comments