When using ArgumentMatchers.refEq() to compare objects in Mockito, excluding top-level fields like address works as expected. However, excluding nested fields such as address.city doesn’t seem to be supported. For instance, calling ArgumentMatchers.refEq(user, "address.city") throws an error or behaves unexpectedly. The user wants to know if there’s a way to ignore nested fields (like city inside address) while still validating the rest of the object properties in refEq().
This is a limitation of refEq(), it only supports excluding top-level fields. Nested fields like address.city cannot be excluded directly.
A common workaround is to manually override equals() in your model to ignore the nested field during comparison, or create a custom matcher using ArgumentMatcher:
verify(mock).save(argThat(user ->
user.getName().equals("John") &&
user.getAddress().getZip().equals("12345")
// ignoring city
));
This gives you full control over which nested fields to include in the comparison.
Yep, I ran into this too. refEq() is convenient for shallow comparisons but doesn’t handle nested exclusions. I usually use argThat() for anything more complex, it’s a bit more verbose, but you can selectively compare any nested property without worrying about refEq limitations.
Another tip: if you often need to ignore certain nested fields, consider writing a helper method that clones the object with ignored fields nulled out, then pass that to refEq(). Example:
User userCopy = cloneUserIgnoringCity(originalUser);
verify(mock).save(refEq(userCopy));
This avoids custom matchers for every test and keeps refEq() usable for most properties.