### Question:
AbstractLocatorAndInvocationHandler extends AbstractLocatorHandler<T> implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object invocationResult = null; if (TO_STRING.equals(method)) { invocationResult = proxyToString(loaded() ? (String) invoke(method, args) : null); } else if (loaded()) { invocationResult = invokeEqualsOnLoadedProxy(method, args, invocationResult); } else { invocationResult = invokeMethodOnUnloadedProxy(proxy, method, args, invocationResult); } if (invocationResult == null) { getLocatorResult(); invocationResult = invokeWithRetry(method, args); } return invocationResult; } AbstractLocatorAndInvocationHandler(ElementLocator locator); @Override Object invoke(Object proxy, Method method, Object[] args); @Override boolean equals(Object obj); @Override int hashCode(); @Override String toString();  }### Answer:
@Test public void testLoadedToString() throws Throwable { WebElement proxy = mock(WebElement.class); Method toString = getMethod("toString"); when(invocationHandler.loaded()).thenReturn(true); when(invocationHandler.getInvocationTarget(toString)).thenReturn(proxy); assertThat(invocationHandler.invoke(proxy, toString, new Object[0])).asString() .startsWith("locator (Mock for WebElement"); }
@Test public void testNotLoadedToString() throws Throwable { WebElement proxy = mock(WebElement.class); Method toString = getMethod("toString"); when(invocationHandler.loaded()).thenReturn(false); assertThat(invocationHandler.invoke(proxy, toString, new Object[0])).asString().isEqualTo("locator (Lazy Element)"); }
@Test public void testLoadedEqualsWithRetry() throws Throwable { WebElement proxy = mock(WebElement.class); Method equals = getMethod("equals", Object.class); Object[] args = {proxy}; when(invocationHandler.loaded()).thenReturn(true); when(invocationHandler.getInvocationTarget(equals)).thenReturn(proxy); assertThat(invocationHandler.invoke(proxy, equals, args)).isEqualTo(true); }
@Test public void testLoadedNotEqualsWithRetry() throws Throwable { WebElement proxy = mock(WebElement.class); Method equals = getMethod("equals", Object.class); Object[] args = {mock(WebElement.class)}; when(invocationHandler.loaded()).thenReturn(true); when(invocationHandler.getInvocationTarget(equals)).thenReturn(proxy); assertThat(invocationHandler.invoke(proxy, equals, args)).isEqualTo(false); }
@Test public void testNotLoadedEqualsWithRetry() throws Throwable { WebElement proxy = mock(WebElement.class); Method equals = getMethod("equals", Object.class); Object[] args = {mock(WebElement.class)}; when(invocationHandler.loaded()).thenReturn(false); when(invocationHandler.getInvocationTarget(equals)).thenReturn(proxy); assertThat(invocationHandler.invoke(proxy, equals, args)).isEqualTo(false); }
@Test public void testNotLoadedNotEqualsWithRetry() throws Throwable { WebElement proxy = mock(WebElement.class); Method equals = getMethod("equals", Object.class); Object[] args = {proxy}; when(invocationHandler.loaded()).thenReturn(false); when(invocationHandler.getInvocationTarget(equals)).thenReturn(proxy); assertThat(invocationHandler.invoke(proxy, equals, args)).isEqualTo(true); }
@Test public void testNotLoadedOtherThanHashCodeWithRetry() throws Throwable { WebElement proxy = mock(WebElement.class); Method isSelected = WebElement.class.getMethod("isSelected"); when(proxy.isSelected()).thenReturn(true); when(invocationHandler.loaded()).thenReturn(false); when(invocationHandler.getInvocationTarget(isSelected)).thenReturn(proxy); assertThat(invocationHandler.invoke(proxy, isSelected, new Object[0])).isEqualTo(true); }