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);
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.
source share