| #region Copyright notice and license | |
| // Protocol Buffers - Google's data interchange format | |
| // Copyright 2008 Google Inc. All rights reserved. | |
| // http://github.com/jskeet/dotnet-protobufs/ | |
| // Original C++/Java/Python code: | |
| // http://code.google.com/p/protobuf/ | |
| // | |
| // Redistribution and use in source and binary forms, with or without | |
| // modification, are permitted provided that the following conditions are | |
| // met: | |
| // | |
| // * Redistributions of source code must retain the above copyright | |
| // notice, this list of conditions and the following disclaimer. | |
| // * Redistributions in binary form must reproduce the above | |
| // copyright notice, this list of conditions and the following disclaimer | |
| // in the documentation and/or other materials provided with the | |
| // distribution. | |
| // * Neither the name of Google Inc. nor the names of its | |
| // contributors may be used to endorse or promote products derived from | |
| // this software without specific prior written permission. | |
| // | |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| #endregion | |
| using System; | |
| using Google.ProtocolBuffers.Descriptors; | |
| using Google.ProtocolBuffers.TestProtos; | |
| using NUnit.Framework; | |
| using Rhino.Mocks; | |
| using Rhino.Mocks.Constraints; | |
| namespace Google.ProtocolBuffers | |
| { | |
| /// <summary> | |
| /// Tests for generated service classes. | |
| /// TODO(jonskeet): Convert the mocking tests using Rhino.Mocks. | |
| /// </summary> | |
| [TestFixture] | |
| public class ServiceTest | |
| { | |
| private delegate void Action<T1, T2>(T1 t1, T2 t2); | |
| private static readonly MethodDescriptor FooDescriptor = TestGenericService.Descriptor.Methods[0]; | |
| private static readonly MethodDescriptor BarDescriptor = TestGenericService.Descriptor.Methods[1]; | |
| [Test] | |
| public void GetRequestPrototype() | |
| { | |
| TestGenericService service = new TestServiceImpl(); | |
| Assert.AreSame(service.GetRequestPrototype(FooDescriptor), FooRequest.DefaultInstance); | |
| Assert.AreSame(service.GetRequestPrototype(BarDescriptor), BarRequest.DefaultInstance); | |
| } | |
| [Test] | |
| public void GetResponsePrototype() | |
| { | |
| TestGenericService service = new TestServiceImpl(); | |
| Assert.AreSame(service.GetResponsePrototype(FooDescriptor), FooResponse.DefaultInstance); | |
| Assert.AreSame(service.GetResponsePrototype(BarDescriptor), BarResponse.DefaultInstance); | |
| } | |
| [Test] | |
| public void CallMethodFoo() | |
| { | |
| MockRepository mocks = new MockRepository(); | |
| FooRequest fooRequest = FooRequest.CreateBuilder().Build(); | |
| FooResponse fooResponse = FooResponse.CreateBuilder().Build(); | |
| IRpcController controller = mocks.StrictMock<IRpcController>(); | |
| bool fooCalled = false; | |
| TestGenericService service = new TestServiceImpl((request, responseAction) => | |
| { | |
| Assert.AreSame(fooRequest, request); | |
| fooCalled = true; | |
| responseAction(fooResponse); | |
| }, null, controller); | |
| bool doneHandlerCalled = false; | |
| Action<IMessage> doneHandler = (response => | |
| { | |
| Assert.AreSame(fooResponse, response); | |
| doneHandlerCalled = true; | |
| }); | |
| using (mocks.Record()) | |
| { | |
| // No mock interactions to record | |
| } | |
| service.CallMethod(FooDescriptor, controller, fooRequest, doneHandler); | |
| Assert.IsTrue(doneHandlerCalled); | |
| Assert.IsTrue(fooCalled); | |
| mocks.VerifyAll(); | |
| } | |
| private delegate void CallFooDelegate(MethodDescriptor descriptor, IRpcController controller, | |
| IMessage request, IMessage response, Action<IMessage> doneHandler); | |
| /// <summary> | |
| /// Tests the generated stub handling of Foo. By this stage we're reasonably confident | |
| /// that the choice between Foo and Bar is arbitrary, hence the lack of a corresponding Bar | |
| /// test. | |
| /// </summary> | |
| [Test] | |
| [Ignore("Crashes Mono - needs further investigation")] | |
| public void GeneratedStubFooCall() | |
| { | |
| FooRequest fooRequest = FooRequest.CreateBuilder().Build(); | |
| MockRepository mocks = new MockRepository(); | |
| IRpcChannel mockChannel = mocks.StrictMock<IRpcChannel>(); | |
| IRpcController mockController = mocks.StrictMock<IRpcController>(); | |
| TestGenericService service = TestGenericService.CreateStub(mockChannel); | |
| Action<FooResponse> doneHandler = mocks.StrictMock<Action<FooResponse>>(); | |
| using (mocks.Record()) | |
| { | |
| // Nasty way of mocking out "the channel calls the done handler". | |
| Expect.Call(() => mockChannel.CallMethod(null, null, null, null, null)) | |
| .IgnoreArguments() | |
| .Constraints(Is.Same(FooDescriptor), Is.Same(mockController), Is.Same(fooRequest), | |
| Is.Same(FooResponse.DefaultInstance), Is.Anything()) | |
| .Do((CallFooDelegate) ((p1, p2, p3, response, done) => done(response))); | |
| doneHandler(FooResponse.DefaultInstance); | |
| } | |
| service.Foo(mockController, fooRequest, doneHandler); | |
| mocks.VerifyAll(); | |
| } | |
| [Test] | |
| public void CallMethodBar() | |
| { | |
| MockRepository mocks = new MockRepository(); | |
| BarRequest barRequest = BarRequest.CreateBuilder().Build(); | |
| BarResponse barResponse = BarResponse.CreateBuilder().Build(); | |
| IRpcController controller = mocks.StrictMock<IRpcController>(); | |
| bool barCalled = false; | |
| TestGenericService service = new TestServiceImpl(null, (request, responseAction) => | |
| { | |
| Assert.AreSame(barRequest, request); | |
| barCalled = true; | |
| responseAction(barResponse); | |
| }, controller); | |
| bool doneHandlerCalled = false; | |
| Action<IMessage> doneHandler = (response => | |
| { | |
| Assert.AreSame(barResponse, response); | |
| doneHandlerCalled = true; | |
| }); | |
| using (mocks.Record()) | |
| { | |
| // No mock interactions to record | |
| } | |
| service.CallMethod(BarDescriptor, controller, barRequest, doneHandler); | |
| Assert.IsTrue(doneHandlerCalled); | |
| Assert.IsTrue(barCalled); | |
| mocks.VerifyAll(); | |
| } | |
| private class TestServiceImpl : TestGenericService | |
| { | |
| private readonly Action<FooRequest, Action<FooResponse>> fooHandler; | |
| private readonly Action<BarRequest, Action<BarResponse>> barHandler; | |
| private readonly IRpcController expectedController; | |
| internal TestServiceImpl() | |
| { | |
| } | |
| internal TestServiceImpl(Action<FooRequest, Action<FooResponse>> fooHandler, | |
| Action<BarRequest, Action<BarResponse>> barHandler, | |
| IRpcController expectedController) | |
| { | |
| this.fooHandler = fooHandler; | |
| this.barHandler = barHandler; | |
| this.expectedController = expectedController; | |
| } | |
| public override void Foo(IRpcController controller, FooRequest request, Action<FooResponse> done) | |
| { | |
| Assert.AreSame(expectedController, controller); | |
| fooHandler(request, done); | |
| } | |
| public override void Bar(IRpcController controller, BarRequest request, Action<BarResponse> done) | |
| { | |
| Assert.AreSame(expectedController, controller); | |
| barHandler(request, done); | |
| } | |
| } | |
| } | |
| } |