Mockito测试如何指定List<Object>类型参数而非仅用Matchers.anyList?
List<Object> Parameter in Mockito Tests Got it, I’ve run into this exact head-scratcher before! The default anyList() matcher is too generic when you need to specifically validate that a method was called with a List<Object> (not just any List type). Here are a couple of practical ways to handle this, considering Java’s type erasure quirk:
Option 1: Use argThat() for Inline Type Checking
Since Java erases generic type information at runtime, we can’t directly check the generic parameter of a List. But we can combine argThat() with checks that fit your scenario:
import org.mockito.ArgumentMatchers; import org.mockito.Mockito; // Create your mock instance MyTargetService mockService = Mockito.mock(MyTargetService.class); // Execute the method you're testing mockService.handleList(new ArrayList<>()); // Verify the method was called with a List<Object> Mockito.verify(mockService).handleList( ArgumentMatchers.argThat(list -> { // First confirm it's a List instance if (!(list instanceof List)) { return false; } // For non-empty lists, you can validate element types (though all objects are Object subclasses) // For empty lists, we can only confirm it's a List (thanks to Java's type erasure) return list.isEmpty() || list.stream().allMatch(item -> item instanceof Object); }) );
Option 2: Create a Custom TypeSafeMatcher
If you need to reuse this check across multiple tests, a custom matcher keeps your test code clean and consistent:
import org.hamcrest.TypeSafeMatcher; public class ListOfObjectMatcher extends TypeSafeMatcher<List<Object>> { @Override protected boolean matchesSafely(List<Object> list) { // Add custom validation logic here (e.g., check element types if your use case requires it) return true; // For basic validation, confirming it's a List is sufficient (due to erasure) } @Override public void describeTo(org.hamcrest.Description description) { description.appendText("a List<Object>"); } // Static helper method for easy test usage public static ListOfObjectMatcher listOfObject() { return new ListOfObjectMatcher(); } }
Then use it in your test like this:
Mockito.verify(mockService).handleList(ArgumentMatchers.argThat(ListOfObjectMatcher.listOfObject()));
Key Note About Type Erasure
It’s critical to remember: Java doesn’t retain generic type information at runtime. So if the List is empty, we can’t definitively distinguish List<Object> from List<String> or any other List type. But if your method’s parameter is explicitly declared as List<Object>, or you have elements in the List to validate, these approaches will work perfectly for your verification needs.
内容的提问来源于stack exchange,提问作者Sue

