blob: ff290742a0d08d29747097d1d3b5b8db72c6c75f [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 Skeete1e84312009-06-25 16:55:08 +010074 IRpcController controller = mocks.StrictMock<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]
Jon Skeete1e84312009-06-25 16:55:08 +0100110 [Ignore("Crashes Mono - needs further investigation")]
Jon Skeet68036862008-10-22 13:30:34 +0100111 public void GeneratedStubFooCall() {
112 FooRequest fooRequest = FooRequest.CreateBuilder().Build();
113 MockRepository mocks = new MockRepository();
Jon Skeete1e84312009-06-25 16:55:08 +0100114 IRpcChannel mockChannel = mocks.StrictMock<IRpcChannel>();
115 IRpcController mockController = mocks.StrictMock<IRpcController>();
Jon Skeet68036862008-10-22 13:30:34 +0100116 TestService service = TestService.CreateStub(mockChannel);
Jon Skeete1e84312009-06-25 16:55:08 +0100117 Action<FooResponse> doneHandler = mocks.StrictMock<Action<FooResponse>>();
Jon Skeet68036862008-10-22 13:30:34 +0100118
119 using (mocks.Record()) {
120
121 // Nasty way of mocking out "the channel calls the done handler".
122 Expect.Call(() => mockChannel.CallMethod(null, null, null, null, null))
123 .IgnoreArguments()
124 .Constraints(Is.Same(FooDescriptor), Is.Same(mockController), Is.Same(fooRequest),
125 Is.Same(FooResponse.DefaultInstance), Is.Anything())
126 .Do((CallFooDelegate) ((p1, p2, p3, response, done) => done(response)));
Jon Skeete1e84312009-06-25 16:55:08 +0100127 doneHandler(FooResponse.DefaultInstance);
Jon Skeet68036862008-10-22 13:30:34 +0100128 }
129
130 service.Foo(mockController, fooRequest, doneHandler);
131
132 mocks.VerifyAll();
133 }
134
135 [Test]
136 public void CallMethodBar() {
137 MockRepository mocks = new MockRepository();
138 BarRequest barRequest = BarRequest.CreateBuilder().Build();
139 BarResponse barResponse = BarResponse.CreateBuilder().Build();
Jon Skeete1e84312009-06-25 16:55:08 +0100140 IRpcController controller = mocks.StrictMock<IRpcController>();
Jon Skeet68036862008-10-22 13:30:34 +0100141
142 bool barCalled = false;
143
144 TestService service = new TestServiceImpl(null, (request, responseAction) => {
145 Assert.AreSame(barRequest, request);
146 barCalled = true;
147 responseAction(barResponse);
148 }, controller);
149
150 bool doneHandlerCalled = false;
151 Action<IMessage> doneHandler = (response => {
152 Assert.AreSame(barResponse, response);
153 doneHandlerCalled = true;
154 });
155
156 using (mocks.Record()) {
157 // No mock interactions to record
158 }
159
160 service.CallMethod(BarDescriptor, controller, barRequest, doneHandler);
161
162 Assert.IsTrue(doneHandlerCalled);
163 Assert.IsTrue(barCalled);
164 mocks.VerifyAll();
165 }
166
167
168 class TestServiceImpl : TestService {
169 private readonly Action<FooRequest, Action<FooResponse>> fooHandler;
170 private readonly Action<BarRequest, Action<BarResponse>> barHandler;
171 private readonly IRpcController expectedController;
172
173 internal TestServiceImpl() {
174 }
175
176 internal TestServiceImpl(Action<FooRequest, Action<FooResponse>> fooHandler,
177 Action<BarRequest, Action<BarResponse>> barHandler,
178 IRpcController expectedController) {
179 this.fooHandler = fooHandler;
180 this.barHandler = barHandler;
181 this.expectedController = expectedController;
182 }
183
184 public override void Foo(IRpcController controller, FooRequest request, Action<FooResponse> done) {
185 Assert.AreSame(expectedController, controller);
186 fooHandler(request, done);
187 }
188
189 public override void Bar(IRpcController controller, BarRequest request, Action<BarResponse> done) {
190 Assert.AreSame(expectedController, controller);
191 barHandler(request, done);
192 }
193 }
194 }
195}