blob: c6899076db8d13e3f14b222325acc7bc2a443624 [file] [log] [blame]
Jon Skeet60c059b2008-10-23 21:17:56 +01001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// http://github.com/jskeet/dotnet-protobufs/
4// Original C++/Java/Python code:
Jon Skeet68036862008-10-22 13:30:34 +01005// http://code.google.com/p/protobuf/
6//
Jon Skeet60c059b2008-10-23 21:17:56 +01007// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met:
Jon Skeet68036862008-10-22 13:30:34 +010010//
Jon Skeet60c059b2008-10-23 21:17:56 +010011// * Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13// * Redistributions in binary form must reproduce the above
14// copyright notice, this list of conditions and the following disclaimer
15// in the documentation and/or other materials provided with the
16// distribution.
17// * Neither the name of Google Inc. nor the names of its
18// contributors may be used to endorse or promote products derived from
19// this software without specific prior written permission.
Jon Skeet68036862008-10-22 13:30:34 +010020//
Jon Skeet60c059b2008-10-23 21:17:56 +010021// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Jon Skeet68036862008-10-22 13:30:34 +010032using System;
33using Google.ProtocolBuffers.Descriptors;
34using Google.ProtocolBuffers.TestProtos;
35using NUnit.Framework;
36using Rhino.Mocks;
37using Rhino.Mocks.Constraints;
38
39namespace Google.ProtocolBuffers {
40
41 /// <summary>
42 /// Tests for generated service classes.
43 /// TODO(jonskeet): Convert the mocking tests using Rhino.Mocks.
44 /// </summary>
45 [TestFixture]
46 public class ServiceTest {
47
48 delegate void Action<T1, T2>(T1 t1, T2 t2);
49
50 private static readonly MethodDescriptor FooDescriptor = TestService.Descriptor.Methods[0];
51 private static readonly MethodDescriptor BarDescriptor = TestService.Descriptor.Methods[1];
52
53 [Test]
54 public void GetRequestPrototype() {
55 TestService service = new TestServiceImpl();
56
57 Assert.AreSame(service.GetRequestPrototype(FooDescriptor), FooRequest.DefaultInstance);
58 Assert.AreSame(service.GetRequestPrototype(BarDescriptor), BarRequest.DefaultInstance);
59 }
60
61 [Test]
62 public void GetResponsePrototype() {
63 TestService service = new TestServiceImpl();
64
65 Assert.AreSame(service.GetResponsePrototype(FooDescriptor), FooResponse.DefaultInstance);
66 Assert.AreSame(service.GetResponsePrototype(BarDescriptor), BarResponse.DefaultInstance);
67 }
68
69 [Test]
70 public void CallMethodFoo() {
71 MockRepository mocks = new MockRepository();
72 FooRequest fooRequest = FooRequest.CreateBuilder().Build();
73 FooResponse fooResponse = FooResponse.CreateBuilder().Build();
Jon Skeetb2526212009-06-25 09:18:02 +010074 IRpcController controller = mocks.StrictMockWithRemoting<IRpcController>();
Jon Skeet68036862008-10-22 13:30:34 +010075
76 bool fooCalled = false;
77
78 TestService service = new TestServiceImpl((request, responseAction) => {
79 Assert.AreSame(fooRequest, request);
80 fooCalled = true;
81 responseAction(fooResponse);
82 }, null, controller);
83
84 bool doneHandlerCalled = false;
85 Action<IMessage> doneHandler = (response => {
86 Assert.AreSame(fooResponse, response);
87 doneHandlerCalled = true;
88 });
89
90 using (mocks.Record()) {
91 // No mock interactions to record
92 }
93
94 service.CallMethod(FooDescriptor, controller, fooRequest, doneHandler);
95
96 Assert.IsTrue(doneHandlerCalled);
97 Assert.IsTrue(fooCalled);
98 mocks.VerifyAll();
99 }
100
101 delegate void CallFooDelegate(MethodDescriptor descriptor, IRpcController controller,
102 IMessage request, IMessage response, Action<IMessage> doneHandler);
103
104 /// <summary>
105 /// Tests the generated stub handling of Foo. By this stage we're reasonably confident
106 /// that the choice between Foo and Bar is arbitrary, hence the lack of a corresponding Bar
107 /// test.
108 /// </summary>
109 [Test]
110 public void GeneratedStubFooCall() {
111 FooRequest fooRequest = FooRequest.CreateBuilder().Build();
112 MockRepository mocks = new MockRepository();
Jon Skeetb2526212009-06-25 09:18:02 +0100113 IRpcChannel mockChannel = mocks.StrictMockWithRemoting<IRpcChannel>();
114 IRpcController mockController = mocks.StrictMockWithRemoting<IRpcController>();
Jon Skeet68036862008-10-22 13:30:34 +0100115 TestService service = TestService.CreateStub(mockChannel);
Jon Skeetb2526212009-06-25 09:18:02 +0100116 bool doneCalled = false;
117 // TODO(jonskeet): Use Rhino for this (to get ordering) when Mono works with it properly
118 Action<FooResponse> doneHandler = response => {
119 Assert.IsFalse(doneCalled);
120 doneCalled = true;
121 Assert.AreEqual(FooResponse.DefaultInstance, response);
122 };
Jon Skeet68036862008-10-22 13:30:34 +0100123
124 using (mocks.Record()) {
125
126 // Nasty way of mocking out "the channel calls the done handler".
127 Expect.Call(() => mockChannel.CallMethod(null, null, null, null, null))
128 .IgnoreArguments()
129 .Constraints(Is.Same(FooDescriptor), Is.Same(mockController), Is.Same(fooRequest),
130 Is.Same(FooResponse.DefaultInstance), Is.Anything())
131 .Do((CallFooDelegate) ((p1, p2, p3, response, done) => done(response)));
Jon Skeet68036862008-10-22 13:30:34 +0100132 }
133
134 service.Foo(mockController, fooRequest, doneHandler);
135
136 mocks.VerifyAll();
137 }
138
139 [Test]
140 public void CallMethodBar() {
141 MockRepository mocks = new MockRepository();
142 BarRequest barRequest = BarRequest.CreateBuilder().Build();
143 BarResponse barResponse = BarResponse.CreateBuilder().Build();
Jon Skeetb2526212009-06-25 09:18:02 +0100144 IRpcController controller = mocks.StrictMockWithRemoting<IRpcController>();
Jon Skeet68036862008-10-22 13:30:34 +0100145
146 bool barCalled = false;
147
148 TestService service = new TestServiceImpl(null, (request, responseAction) => {
149 Assert.AreSame(barRequest, request);
150 barCalled = true;
151 responseAction(barResponse);
152 }, controller);
153
154 bool doneHandlerCalled = false;
155 Action<IMessage> doneHandler = (response => {
156 Assert.AreSame(barResponse, response);
157 doneHandlerCalled = true;
158 });
159
160 using (mocks.Record()) {
161 // No mock interactions to record
162 }
163
164 service.CallMethod(BarDescriptor, controller, barRequest, doneHandler);
165
166 Assert.IsTrue(doneHandlerCalled);
167 Assert.IsTrue(barCalled);
168 mocks.VerifyAll();
169 }
170
171
172 class TestServiceImpl : TestService {
173 private readonly Action<FooRequest, Action<FooResponse>> fooHandler;
174 private readonly Action<BarRequest, Action<BarResponse>> barHandler;
175 private readonly IRpcController expectedController;
176
177 internal TestServiceImpl() {
178 }
179
180 internal TestServiceImpl(Action<FooRequest, Action<FooResponse>> fooHandler,
181 Action<BarRequest, Action<BarResponse>> barHandler,
182 IRpcController expectedController) {
183 this.fooHandler = fooHandler;
184 this.barHandler = barHandler;
185 this.expectedController = expectedController;
186 }
187
188 public override void Foo(IRpcController controller, FooRequest request, Action<FooResponse> done) {
189 Assert.AreSame(expectedController, controller);
190 fooHandler(request, done);
191 }
192
193 public override void Bar(IRpcController controller, BarRequest request, Action<BarResponse> done) {
194 Assert.AreSame(expectedController, controller);
195 barHandler(request, done);
196 }
197 }
198 }
199}