I have the following test where I need to verify that all getters of the Person class are being called. So far I have used mockito's verify() to make sure that each getter is called. Is there a way to do that by reflection? It can be the case that a new getter is added to the Person class but the test will miss that.
public class GetterTest {
class Person{
private String firstname;
private String lastname;
public String getFirstname() {
return firstname;
}
public String getLastname() {
return lastname;
}
}
@Test
public void testAllGettersCalled() throws IntrospectionException{
Person personMock = mock(Person.class);
personMock.getFirstname();
personMock.getLastname();
for(PropertyDescriptor property : Introspector.getBeanInfo(Person.class).getPropertyDescriptors()) {
verify(personMock, atLeast(1)).getFirstname();
//**How to verify against any getter method and not just getFirstName()???**
}
}
}
The getter method returns the value of the attribute. The setter method takes a parameter and assigns it to the attribute. Once the getter and setter have been defined, we use it in our main: public static void main(String[] args) { Vehicle v1 = new Vehicle(); v1. setColor("Red"); System. out.
The @Getter annotation is used to generate the default getter implementation for fields that are annotated with the annotation. This annotation can also be used at the class level in which Lombok will generate the getter methods for all fields.
Getters and Setters play an important role in retrieving and updating the value of a variable outside the encapsulating class. A setter updates the value of a variable, while a getter reads the value of a variable.
Getter returns the value (accessors), it returns the value of data type int, String, double, float, etc. For the program's convenience, getter starts with the word “get” followed by the variable name. While Setter sets or updates the value (mutators). It sets the value for any variable used in a class's programs.
Generally, don't mock the class under test. If your test is for a Person, you shouldn't ever see Mockito.mock(Person.class)
in it, as that's a pretty clear sign that you're testing the mocking framework instead of the system-under-test.
Instead, you may want to create a spy(new Person())
, which will create a real Person implementation using a real constructor and then copy its data to a Mockito-generated proxy. You can use MockingDetails.getInvocations()
to reflectively check that every getter was called.
// This code is untested, but should get the point across. Edits welcome.
// 2016-01-20: Integrated feedback from Georgios Stathis. Thanks Georgios!
@Test
public void callAllGetters() throws Exception {
Person personSpy = spy(new Person());
personSpy.getFirstname();
personSpy.getLastname();
assertAllGettersCalled(personSpy, Person.class);
}
private static void assertAllGettersCalled(Object spy, Class<?> clazz) {
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
Set<Method> setOfDescriptors = beanInfo.getPropertyDescriptors()
.stream()
.map(PropertyDescriptor::getReadMethod)
.filter(p -> !p.getName().contains("getClass"))
.collect(Collectors.toSet());
MockingDetails details = Mockito.mockingDetails(spy);
Set<Method> setOfTestedMethods = details.getInvocations()
.stream()
.map(InvocationOnMock::getMethod)
.collect(Collectors.toSet());
setOfDescriptors.removeAll(setOfTestedMethods);
// The only remaining descriptors are untested.
assertThat(setOfDescriptors).isEmpty();
}
There might be a way to call verify
and invoke
on the Mockito-generated spy, but that seems very fragile, and very dependent on Mockito internals.
As an aside, testing bean-style getters seems like an odd use of time/effort. In general focus on testing implementations that are likely to change or break.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With