-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Description
I was working with a test helper method a colleague wrote that took in an arbitrary status code Matcher
to test whether a status code matched a particular value, which was implemented under the hood using StatusResultMathers.is(Matcher<Integer> matcher)
. I had one use case where I didn't actually care to assert anything, so I wanted to pass in Hamcrest's Matchers.anything()
to the method. However, Matchers.anything()
returns a Matcher<Object>
, not a Matcher<Integer>
, so it cannot be used with StatusResultMathers.is
.
I ended up rewriting my test to not require the use of this matcher, but regardless of this fact, pretty much any method that takes in a specific type of Matcher
to match against an object (e.g. Matcher<Integer>
) should be allowed to take in a Matcher
that matches a superclass as well, since that's still applicable to the object being matched.
Therefore, I propose that this method (and any other such test method in Spring Test) have its input type relaxed to allow the given type or any supertype. For this specific case, StatusResultMathers.is(Matcher<Integer> matcher)
should be changed to StatusResultMathers.is(Matcher<? super Integer> matcher)
.
Example
This fails to compile:
MockMvcResultMatchers.status().is(Matchers.anything());
Methods with this issue
A quick search of the Spring Test project reveals the following methods that could have their generics widened:
org.springframework.test.web.servlet.result.HeaderResultMatchers.stringValues(String name, Matcher<Iterable<String>> matcher)
=>stringValues(String name, Matcher<? super Iterable<? super String>> matcher)
org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo(Matcher<String> matcher)
org.springframework.test.web.servlet.result.StatusResultMatchers.is(Matcher<Integer> matcher)
org.springframework.test.web.reactive.server.XpathAssertions.nodeCount(Matcher<Integer> matcher)
org.springframework.test.util.XpathExpectationsHelper.assertNodeCount(byte[] content, String encoding, Matcher<Integer> matcher)
org.springframework.test.web.client.match.XpathRequestMatchers.nodeCount(Matcher<Integer> matcher)
org.springframework.test.web.servlet.result.XpathResultMatchers.nodeCount(Matcher<Integer> matcher)
Additionally, there are five methods containing Matcher<T> matcher, Class<T> targetType
which I think could be widened to being Matcher<? super T> matcher, Class<T> targetType
to allow a more general Matcher
than the target type:
JsonPathAssertions.value(Matcher<T> matcher, Class<T> targetType)
JsonPathExpectationsHelper.assertValue(String content, Matcher<T> matcher, Class<T> targetType)
JsonPathRequestMatchers.value(Matcher<T> matcher, Class<T> targetType)
JsonPathResultMatchers.value(Matcher<T> matcher, Class<T> targetType)
MockMvcResultMatchers.jsonPath(String expression, Matcher<T> matcher, Class<T> targetType)