core: pull out reusable forwarding test, refactoring forwarding tests (#3480)

This commit is contained in:
zpencer 2018-02-08 16:31:23 -08:00 committed by GitHub
parent bc3e4e9a85
commit d2c7e33f3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 197 additions and 56 deletions

View File

@ -19,11 +19,11 @@ package io.grpc;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import com.google.common.base.Defaults;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@ -45,20 +45,12 @@ public class ForwardingChannelBuilderTest {
}
@Test
public void allBuilderMethodsForwarded() throws Exception {
for (Method method : ManagedChannelBuilder.class.getDeclaredMethods()) {
if (Modifier.isStatic(method.getModifiers()) || Modifier.isPrivate(method.getModifiers())) {
continue;
}
Class<?>[] argTypes = method.getParameterTypes();
Object[] args = new Object[argTypes.length];
for (int i = 0; i < argTypes.length; i++) {
args[i] = Defaults.defaultValue(argTypes[i]);
}
method.invoke(testChannelBuilder, args);
method.invoke(verify(mockDelegate), args);
}
public void allMethodsForwarded() throws Exception {
ForwardingTestUtil.testMethodsForwarded(
ManagedChannelBuilder.class,
mockDelegate,
testChannelBuilder,
Collections.<Method>emptyList());
}
@Test

View File

@ -19,6 +19,8 @@ package io.grpc;
import static org.mockito.Mockito.verify;
import io.grpc.ForwardingServerCallListener.SimpleForwardingServerCallListener;
import java.lang.reflect.Method;
import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -26,51 +28,32 @@ import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* Unit tests for {@link ForwardingServerCallListener}.
*/
@RunWith(JUnit4.class)
public class ForwardingServerCallListenerTest {
@Mock private ServerCall.Listener<Void> serverCallListener;
private ForwardingServerCallListener<Void> forwarder;
@Mock private ServerCall.Listener<Integer> serverCallListener;
private ForwardingServerCallListener<Integer> forwarder;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
forwarder = new SimpleForwardingServerCallListener<Void>(serverCallListener) {};
forwarder = new SimpleForwardingServerCallListener<Integer>(serverCallListener) {};
}
@Test
public void allMethodsForwarded() throws Exception {
ForwardingTestUtil.testMethodsForwarded(
ServerCall.Listener.class, serverCallListener, forwarder, Collections.<Method>emptyList());
}
@Test
public void onMessage() {
forwarder.onMessage(null);
forwarder.onMessage(12345);
verify(serverCallListener).onMessage(null);
}
@Test
public void onHalfClose() {
forwarder.onHalfClose();
verify(serverCallListener).onHalfClose();
}
@Test
public void onCancel() {
forwarder.onCancel();
verify(serverCallListener).onCancel();
}
@Test
public void onComplete() {
forwarder.onComplete();
verify(serverCallListener).onComplete();
}
@Test
public void onReady() {
forwarder.onReady();
verify(serverCallListener).onReady();
verify(serverCallListener).onMessage(12345);
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright 2017, gRPC Authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
import static junit.framework.TestCase.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mockingDetails;
import static org.mockito.Mockito.verify;
import com.google.common.base.Defaults;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
/**
* A util class to help test forwarding classes.
*/
public final class ForwardingTestUtil {
/**
* Use reflection to perform a basic sanity test. The forwarding class should forward all public
* methods to the delegate, except for those in skippedMethods.
* This does NOT verify that arguments or return values are forwarded properly. It only alerts
* the developer if a forward method is missing.
*
* @param delegateClass The class whose methods should be forwarded.
* @param mockDelegate The mockito mock of the delegate class.
* @param forwarder The forwarder object that forwards to the mockDelegate.
* @param skippedMethods A collection of methods that are skipped by the test.
*/
public static <T> void testMethodsForwarded(
Class<T> delegateClass,
T mockDelegate,
T forwarder,
Collection<Method> skippedMethods) throws Exception {
assertTrue(mockingDetails(mockDelegate).isMock());
assertFalse(mockingDetails(forwarder).isMock());
for (Method method : delegateClass.getDeclaredMethods()) {
if (Modifier.isStatic(method.getModifiers())
|| Modifier.isPrivate(method.getModifiers())
|| skippedMethods.contains(method)) {
continue;
}
Class<?>[] argTypes = method.getParameterTypes();
Object[] args = new Object[argTypes.length];
for (int i = 0; i < argTypes.length; i++) {
args[i] = Defaults.defaultValue(argTypes[i]);
}
method.invoke(forwarder, args);
try {
method.invoke(verify(mockDelegate), args);
} catch (InvocationTargetException e) {
throw new AssertionError(String.format("Method was not forwarded: %s", method));
}
}
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright 2017, gRPC Authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.internal;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import io.grpc.Attributes;
import io.grpc.EquivalentAddressGroup;
import io.grpc.ForwardingTestUtil;
import io.grpc.NameResolver;
import io.grpc.Status;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* Unit tests for {@link ForwardingNameResolver}.
*/
@RunWith(JUnit4.class)
public class ForwardingNameResolverTest {
private final NameResolver delegate = mock(NameResolver.class);
private final NameResolver forwarder = new ForwardingNameResolver(delegate) {
};
@Test
public void allMethodsForwarded() throws Exception {
ForwardingTestUtil.testMethodsForwarded(
NameResolver.class,
delegate,
forwarder,
Collections.<Method>emptyList());
}
@Test
public void getServiceAuthority() {
String auth = "example.com";
when(delegate.getServiceAuthority()).thenReturn(auth);
assertEquals(auth, forwarder.getServiceAuthority());
}
@Test
public void start() {
NameResolver.Listener listener = new NameResolver.Listener() {
@Override
public void onAddresses(List<EquivalentAddressGroup> servers, Attributes attributes) { }
@Override
public void onError(Status error) { }
};
forwarder.start(listener);
verify(delegate).start(listener);
}
}

View File

@ -17,10 +17,16 @@
package io.grpc.internal;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import io.grpc.ForwardingTestUtil;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -43,6 +49,15 @@ public class ForwardingReadableBufferTest {
buffer = new ForwardingReadableBuffer(delegate) {};
}
@Test
public void allMethodsForwarded() throws Exception {
ForwardingTestUtil.testMethodsForwarded(
ReadableBuffer.class,
delegate,
buffer,
Collections.<Method>emptyList());
}
@Test
public void readableBytes() {
when(delegate.readableBytes()).thenReturn(1);
@ -73,23 +88,26 @@ public class ForwardingReadableBufferTest {
@Test
public void readBytes() {
buffer.readBytes(null, 1, 2);
byte[] dest = new byte[1];
buffer.readBytes(dest, 1, 2);
verify(delegate).readBytes(null, 1, 2);
verify(delegate).readBytes(dest, 1, 2);
}
@Test
public void readBytes_overload1() {
buffer.readBytes(null);
ByteBuffer dest = mock(ByteBuffer.class);
buffer.readBytes(dest);
verify(delegate).readBytes(null);
verify(delegate).readBytes(dest);
}
@Test
public void readBytes_overload2() throws IOException {
buffer.readBytes(null, 1);
OutputStream dest = mock(OutputStream.class);
buffer.readBytes(dest, 1);
verify(delegate).readBytes(null, 1);
verify(delegate).readBytes(dest, 1);
}
@Test
@ -108,9 +126,10 @@ public class ForwardingReadableBufferTest {
@Test
public void array() {
when(delegate.array()).thenReturn(null);
byte[] array = new byte[1];
when(delegate.array()).thenReturn(array);
assertEquals(null, buffer.array());
assertEquals(array, buffer.array());
}
@Test