• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 package com.google.protobuf;
9 
10 import static com.google.common.truth.Truth.assertThat;
11 import static com.google.common.truth.Truth.assertWithMessage;
12 import static org.mockito.Mockito.verify;
13 import static org.mockito.Mockito.when;
14 
15 import com.google.protobuf.Descriptors.FileDescriptor;
16 import com.google.protobuf.Descriptors.MethodDescriptor;
17 import protobuf_unittest.MessageWithNoOuter;
18 import protobuf_unittest.ServiceWithNoOuter;
19 import protobuf_unittest.UnittestProto.BarRequest;
20 import protobuf_unittest.UnittestProto.BarResponse;
21 import protobuf_unittest.UnittestProto.FooRequest;
22 import protobuf_unittest.UnittestProto.FooResponse;
23 import protobuf_unittest.UnittestProto.TestAllTypes;
24 import protobuf_unittest.UnittestProto.TestService;
25 import protobuf_unittest.no_generic_services_test.UnittestNoGenericServices;
26 import java.util.HashSet;
27 import java.util.Set;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.junit.runners.JUnit4;
31 import org.mockito.InOrder;
32 import org.mockito.Mockito;
33 
34 @RunWith(JUnit4.class)
35 public class ServiceTest {
36   private final Descriptors.MethodDescriptor fooDescriptor =
37       TestService.getDescriptor().getMethods().get(0);
38   private final Descriptors.MethodDescriptor barDescriptor =
39       TestService.getDescriptor().getMethods().get(1);
40   private static final FooRequest FOO_REQUEST = FooRequest.getDefaultInstance();
41   private static final BarRequest BAR_REQUEST = BarRequest.getDefaultInstance();
42   private static final RpcController MOCK_RPC_CONTROLLER = Mockito.mock(RpcController.class);
43   private static final FooResponse FOO_RESPONSE = FooResponse.getDefaultInstance();
44   private static final BarResponse BAR_RESPONSE = BarResponse.getDefaultInstance();
45   private static final MessageWithNoOuter MESSAGE_WITH_NO_OUTER =
46       MessageWithNoOuter.getDefaultInstance();
47 
48   /** Tests Service.callMethod(). */
49   @Test
50   @SuppressWarnings({"unchecked", "rawtypes"})
testCallMethod()51   public void testCallMethod() throws Exception {
52     TestService mockService = Mockito.mock(TestService.class);
53     RpcCallback mockFooRpcCallback = Mockito.mock(RpcCallback.class);
54     RpcCallback mockBarRpcCallback = Mockito.mock(RpcCallback.class);
55     InOrder order = Mockito.inOrder(mockService);
56 
57     mockService.callMethod(fooDescriptor, MOCK_RPC_CONTROLLER, FOO_REQUEST, mockFooRpcCallback);
58     mockService.callMethod(barDescriptor, MOCK_RPC_CONTROLLER, BAR_REQUEST, mockBarRpcCallback);
59     order
60         .verify(mockService)
61         .foo(
62             Mockito.same(MOCK_RPC_CONTROLLER),
63             Mockito.same(FOO_REQUEST),
64             Mockito.same(mockFooRpcCallback));
65     order
66         .verify(mockService)
67         .bar(
68             Mockito.same(MOCK_RPC_CONTROLLER),
69             Mockito.same(BAR_REQUEST),
70             Mockito.same(mockBarRpcCallback));
71   }
72 
73   /** Tests Service.get{Request,Response}Prototype(). */
74   @Test
testGetPrototype()75   public void testGetPrototype() throws Exception {
76     Descriptors.MethodDescriptor fooDescriptor = TestService.getDescriptor().getMethods().get(0);
77     Descriptors.MethodDescriptor barDescriptor = TestService.getDescriptor().getMethods().get(1);
78     TestService mockService = Mockito.mock(TestService.class);
79 
80     assertThat(mockService.getRequestPrototype(fooDescriptor)).isSameInstanceAs(FOO_REQUEST);
81     assertThat(mockService.getResponsePrototype(fooDescriptor)).isSameInstanceAs(FOO_RESPONSE);
82     assertThat(mockService.getRequestPrototype(barDescriptor)).isSameInstanceAs(BAR_REQUEST);
83     assertThat(mockService.getResponsePrototype(barDescriptor)).isSameInstanceAs(BAR_RESPONSE);
84   }
85 
86   /** Tests generated stubs. */
87   @Test
88   @SuppressWarnings({"unchecked", "rawtypes"})
testStub()89   public void testStub() throws Exception {
90     RpcCallback mockFooRpcCallback = Mockito.mock(RpcCallback.class);
91     RpcCallback mockBarRpcCallback = Mockito.mock(RpcCallback.class);
92     RpcChannel mockRpcChannel = Mockito.mock(RpcChannel.class);
93     InOrder order = Mockito.inOrder(mockRpcChannel);
94     TestService stub = TestService.newStub(mockRpcChannel);
95 
96     stub.foo(MOCK_RPC_CONTROLLER, FOO_REQUEST, mockFooRpcCallback);
97     stub.bar(MOCK_RPC_CONTROLLER, BAR_REQUEST, mockBarRpcCallback);
98 
99     order
100         .verify(mockRpcChannel)
101         .callMethod(
102             Mockito.same(fooDescriptor),
103             Mockito.same(MOCK_RPC_CONTROLLER),
104             Mockito.same(FOO_REQUEST),
105             Mockito.same(FOO_RESPONSE),
106             Mockito.any(RpcCallback.class));
107     order
108         .verify(mockRpcChannel)
109         .callMethod(
110             Mockito.same(barDescriptor),
111             Mockito.same(MOCK_RPC_CONTROLLER),
112             Mockito.same(BAR_REQUEST),
113             Mockito.same(BAR_RESPONSE),
114             Mockito.any(RpcCallback.class));
115   }
116 
117   /** Tests generated blocking stubs. */
118   @Test
testBlockingStub()119   public void testBlockingStub() throws Exception {
120     BlockingRpcChannel mockBlockingRpcChannel = Mockito.mock(BlockingRpcChannel.class);
121     TestService.BlockingInterface stub = TestService.newBlockingStub(mockBlockingRpcChannel);
122 
123     when(mockBlockingRpcChannel.callBlockingMethod(
124             Mockito.same(fooDescriptor),
125             Mockito.same(MOCK_RPC_CONTROLLER),
126             Mockito.same(FOO_REQUEST),
127             Mockito.same(FOO_RESPONSE)))
128         .thenReturn(FOO_RESPONSE);
129     when(mockBlockingRpcChannel.callBlockingMethod(
130             Mockito.same(barDescriptor),
131             Mockito.same(MOCK_RPC_CONTROLLER),
132             Mockito.same(BAR_REQUEST),
133             Mockito.same(BAR_RESPONSE)))
134         .thenReturn(BAR_RESPONSE);
135 
136     assertThat(FOO_RESPONSE).isSameInstanceAs(stub.foo(MOCK_RPC_CONTROLLER, FOO_REQUEST));
137     assertThat(BAR_RESPONSE).isSameInstanceAs(stub.bar(MOCK_RPC_CONTROLLER, BAR_REQUEST));
138   }
139 
140   @Test
testNewReflectiveService()141   public void testNewReflectiveService() {
142     ServiceWithNoOuter.Interface impl = Mockito.mock(ServiceWithNoOuter.Interface.class);
143     Service service = ServiceWithNoOuter.newReflectiveService(impl);
144 
145     MethodDescriptor fooMethod = ServiceWithNoOuter.getDescriptor().findMethodByName("Foo");
146     RpcCallback<Message> callback =
147         new RpcCallback<Message>() {
148           @Override
149           public void run(Message parameter) {
150             // No reason this should be run.
151             assertWithMessage("should not run").fail();
152           }
153         };
154     RpcCallback<TestAllTypes> specializedCallback = RpcUtil.specializeCallback(callback);
155 
156     service.callMethod(fooMethod, MOCK_RPC_CONTROLLER, MESSAGE_WITH_NO_OUTER, callback);
157     verify(impl)
158         .foo(
159             Mockito.same(MOCK_RPC_CONTROLLER),
160             Mockito.same(MESSAGE_WITH_NO_OUTER),
161             Mockito.same(specializedCallback));
162   }
163 
164   @Test
testNewReflectiveBlockingService()165   public void testNewReflectiveBlockingService() throws ServiceException {
166     ServiceWithNoOuter.BlockingInterface impl =
167         Mockito.mock(ServiceWithNoOuter.BlockingInterface.class);
168 
169     BlockingService service = ServiceWithNoOuter.newReflectiveBlockingService(impl);
170 
171     MethodDescriptor fooMethod = ServiceWithNoOuter.getDescriptor().findMethodByName("Foo");
172 
173     TestAllTypes expectedResponse = TestAllTypes.getDefaultInstance();
174 
175     when(impl.foo(Mockito.same(MOCK_RPC_CONTROLLER), Mockito.same(MESSAGE_WITH_NO_OUTER)))
176         .thenReturn(expectedResponse);
177     Message response =
178         service.callBlockingMethod(fooMethod, MOCK_RPC_CONTROLLER, MESSAGE_WITH_NO_OUTER);
179     assertThat(response).isEqualTo(expectedResponse);
180   }
181 
182   @Test
testNoGenericServices()183   public void testNoGenericServices() throws Exception {
184     // Non-services should be usable.
185     UnittestNoGenericServices.TestMessage message =
186         UnittestNoGenericServices.TestMessage.newBuilder()
187             .setA(123)
188             .setExtension(UnittestNoGenericServices.testExtension, 456)
189             .build();
190     assertThat(message.getA()).isEqualTo(123);
191     assertThat(UnittestNoGenericServices.TestEnum.FOO.getNumber()).isEqualTo(1);
192 
193     // Build a list of the class names nested in UnittestNoGenericServices.
194     String outerName =
195         "protobuf_unittest.no_generic_services_test.UnittestNoGenericServices";
196     Class<?> outerClass = Class.forName(outerName);
197 
198     Set<String> innerClassNames = new HashSet<>();
199     for (Class<?> innerClass : outerClass.getClasses()) {
200       String fullName = innerClass.getName();
201       // Figure out the unqualified name of the inner class.
202       // Note:  Surprisingly, the full name of an inner class will be separated
203       //   from the outer class name by a '$' rather than a '.'.  This is not
204       //   mentioned in the documentation for java.lang.Class.  I don't want to
205       //   make assumptions, so I'm just going to accept any character as the
206       //   separator.
207       assertThat(fullName).startsWith(outerName);
208 
209       if (!Service.class.isAssignableFrom(innerClass)
210           && !Message.class.isAssignableFrom(innerClass)
211           && !ProtocolMessageEnum.class.isAssignableFrom(innerClass)) {
212         // Ignore any classes not generated by the base code generator.
213         continue;
214       }
215 
216       innerClassNames.add(fullName.substring(outerName.length() + 1));
217     }
218 
219     // No service class should have been generated.
220     assertThat(innerClassNames).contains("TestMessage");
221     assertThat(innerClassNames).contains("TestEnum");
222     assertThat(innerClassNames).doesNotContain("TestService");
223 
224     // But descriptors are there.
225     FileDescriptor file = UnittestNoGenericServices.getDescriptor();
226     assertThat(file.getServices()).hasSize(1);
227     assertThat(file.getServices().get(0).getName()).isEqualTo("TestService");
228     assertThat(file.getServices().get(0).getMethods()).hasSize(1);
229     assertThat(file.getServices().get(0).getMethods().get(0).getName()).isEqualTo("Foo");
230   }
231 }
232