Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verify that all getter methods are called

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()???**
        }
    }
}
like image 249
Georgios Stathis Avatar asked Jan 13 '16 17:01

Georgios Stathis


People also ask

What is the getter method?

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.

What is @getter annotation in Java?

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.

What is @getter and @setter in spring boot?

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.

What is @getter and @setter?

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.


1 Answers

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.

like image 193
Jeff Bowman Avatar answered Nov 10 '22 16:11

Jeff Bowman