• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 The gRPC Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.grpc;
18 
19 import static junit.framework.TestCase.assertFalse;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertTrue;
22 import static org.mockito.Mockito.mockingDetails;
23 import static org.mockito.Mockito.verify;
24 
25 import com.google.common.base.Defaults;
26 import com.google.common.base.MoreObjects;
27 import java.lang.reflect.InvocationTargetException;
28 import java.lang.reflect.Method;
29 import java.lang.reflect.Modifier;
30 import java.util.Collection;
31 
32 /**
33  * A util class to help test forwarding classes.
34  */
35 public final class ForwardingTestUtil {
36   /**
37    * Use reflection to perform a basic sanity test. The forwarding class should forward all public
38    * methods to the delegate, except for those in skippedMethods.
39    * This does NOT verify that arguments or return values are forwarded properly. It only alerts
40    * the developer if a forward method is missing.
41    *
42    * @param delegateClass The class whose methods should be forwarded.
43    * @param mockDelegate The mockito mock of the delegate class.
44    * @param forwarder The forwarder object that forwards to the mockDelegate.
45    * @param skippedMethods A collection of methods that are skipped by the test.
46    */
testMethodsForwarded( Class<T> delegateClass, T mockDelegate, T forwarder, Collection<Method> skippedMethods)47   public static <T> void testMethodsForwarded(
48       Class<T> delegateClass,
49       T mockDelegate,
50       T forwarder,
51       Collection<Method> skippedMethods) throws Exception {
52     assertTrue(mockingDetails(mockDelegate).isMock());
53     assertFalse(mockingDetails(forwarder).isMock());
54 
55     for (Method method : delegateClass.getDeclaredMethods()) {
56       if (Modifier.isStatic(method.getModifiers())
57           || Modifier.isPrivate(method.getModifiers())
58           || skippedMethods.contains(method)) {
59         continue;
60       }
61       Class<?>[] argTypes = method.getParameterTypes();
62       Object[] args = new Object[argTypes.length];
63       for (int i = 0; i < argTypes.length; i++) {
64         args[i] = Defaults.defaultValue(argTypes[i]);
65       }
66       method.invoke(forwarder, args);
67       try {
68         method.invoke(verify(mockDelegate), args);
69       } catch (InvocationTargetException e) {
70         throw new AssertionError(String.format("Method was not forwarded: %s", method));
71       }
72     }
73 
74     boolean skipToString = false;
75     for (Method method : skippedMethods) {
76       if (method.getName().equals("toString")) {
77         skipToString = true;
78         break;
79       }
80     }
81     if (!skipToString) {
82       String actual = forwarder.toString();
83       String expected =
84           MoreObjects.toStringHelper(forwarder).add("delegate", mockDelegate).toString();
85       assertEquals("Method toString() was not forwarded properly", expected, actual);
86     }
87   }
88 }
89