Make sure all getter methods are called.

I have the following test where I need to check that all getters of the Person class are called. So far, I have used mockito verify () to make sure every getter is called. Is there a way to do this through reflection? This may be the case when a new getter is added to the Person class, but the test will skip this.

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()???** } } } 
+6
source share
2 answers

As a rule, do not scoff at the tested class. If your test is for the Person, you should never see Mockito.mock(Person.class) , which is a pretty clear sign that you are checking the mock structure instead of the system test.

Instead, you may need to create spy(new Person()) , which will create a real implementation of Person using a real constructor, and then copy its data to the proxy created by Mockito. You can use MockingDetails.getInvocations() to reflect that every getter has been 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 may be a way to invoke verify and invoke for the spy created by Mockito, but it seems very fragile and very dependent on the internal functions of Mockito.

As an aside, testing bean-line getters seems like an odd use of time / effort. In general, focus on testing that may change or break.

+6
source

I can think of two solutions for your problem:

  • Generate Builder code programmatically, so you do not need to run tests. Java code is generated by the program and is never edited by the user. Instead, test the generator. Use a text template and create definitions from a serialized domain model or directly from compiled Java classes (you will need a separate bean-dependent module)

  • Write your tests against the proxy library. The problem is that regular proxies can implement interfaces, not regular classes, and it is very cumbersome to have interfaces for Javabeans. If you choose this route, I will switch from Javassist . I encoded a runnable sample and put it on GitHub . Test cases use factory proxy to instantiate beans (instead of using new )

 public class CountingCallsProxyFactory { public <T> T proxy(Class<T> classToProxy) { ProxyFactory factory = new ProxyFactory(); factory.setSuperclass(classToProxy); Class clazz = factory.createClass(); T instance = (T) clazz.newInstance(); ProxyObject proxy = (ProxyObject) instance; MethodCallCounter handler = new MethodCallCounter(); proxy.setHandler(handler); return instance; } public void verifyAllGettersCalled(Object bean) { // Query the counter against the properties in the bean } } 

The counter is stored inside the MethodCallCounter class

0
source

All Articles