public void HandleCall(MockingProxy proxy, MockableCall call) { using (new RecorderManager.Lock()) { call.SetResult(InvokeOnServer(proxy, call)); RecorderManager.RecordCall(call); } }
private IMethodReturnMessage InvokeOnServer(MockingProxy proxy, MockableCall call) { IMessage request = call.OriginalCall; IMethodCallMessage mcm = request as IMethodCallMessage; IConstructionCallMessage ccm = request as IConstructionCallMessage; if(ccm != null) { try { // Attach server instance: // (we do it only for MarshalByRefObjects as it's a requirement, don't really // know however what's the added value of attachingToServer... it also works // well without doing this) if (this.serverInstance is MarshalByRefObject) proxy.AttachServer((MarshalByRefObject)this.serverInstance); // Call instance constructor: RemotingServices.GetRealProxy(serverInstance).InitializeServerObject(ccm); // Build response: return MockingTools.BuildReturnMessage(proxy.GetTransparentProxy(), ccm.Args, mcm); } catch (Exception ex) { // Build response: return MockingTools.BuildReturnMessage(ex, mcm); } } else { try { // Invoke instance method: object[] args = new object[mcm.ArgCount]; mcm.Args.CopyTo(args, 0); object result = mcm.MethodBase.Invoke(serverInstance, args); // Build response: return MockingTools.BuildReturnMessage(result, args, mcm); } catch (TargetInvocationException ex) { // Build response: return MockingTools.BuildReturnMessage(ex.InnerException, mcm); } } }
public void Serialization01Test() { MemoryStream buffer = new MemoryStream(); IFormatter formatter = new global::System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); // Create some call: ArrayList result = new ArrayList(); result.Add("One"); result.Add("Two"); MockingProxy callee = new MockingProxy(typeof(Sample.FooBar), null, "m1"); MockableCall call = new MockableCall(callee, typeof(Sample.FooBar).GetMethod("SomeMethodWithInsAndOuts"), new object[] { 1, 2, null, 3 }); call.SetCallResult(result, new object[] { 7, 13 }); // Serialize it: formatter.Serialize(buffer, call); buffer.Flush(); // Deserialize it: buffer.Position = 0; MockableCall deserializedCall = (MockableCall)formatter.Deserialize(buffer); // Test result: Assert.IsNotNull(deserializedCall); Assert.IsFalse(deserializedCall.IsConstructorCall); Assert.IsNotNull(deserializedCall.Method); Assert.AreEqual("SomeMethodWithInsAndOuts", deserializedCall.Method.Name); Assert.AreEqual("Two", ((ArrayList)deserializedCall.ReturnValue)[1]); Assert.AreEqual(3, deserializedCall.InArgs[2]); Assert.AreEqual(13, deserializedCall.OutArgs[1]); Assert.IsTrue(deserializedCall.IsCompleted); }
/// <summary> /// Records the given call. /// </summary> public static void RecordCall(MockableCall call) { if (recordNestLevel == 1) { recorder.RecordCall(call); } else if (recordNestLevel == 0) { throw new InvalidOperationException("RecorderManager should be locked before recording a call."); } }
public override IMessage Invoke(IMessage msg) { MockableCall call = new MockableCall(this, (IMethodCallMessage)msg); this.mocker.HandleCall(this, call); IMethodCallMessage mcm = msg as IMethodCallMessage; if (call.Exception != null) { return new ReturnMessage(call.Exception, mcm); } else if (call.IsConstructorCall) { return EnterpriseServicesHelper.CreateConstructionReturnMessage((IConstructionCallMessage)msg, (MarshalByRefObject)this.GetTransparentProxy()); } else { return new ReturnMessage(call.ReturnValue, call.Args, call.GetOutParameters().Length, mcm.LogicalCallContext, mcm); } }
/// <summary> /// Set the result of the call by copying the result of another call. /// </summary> public virtual void SetResult(MockableCall call) { if (call.Exception != null) { this.SetExceptionResult(call.Exception); } else if (this.IsConstructorCall) { this.SetConstructionResult(call.callee.InstanceName, call.OutArgs); } else { this.SetCallResult(call.ReturnValue, call.OutArgs); } }
public override IMessage Invoke(IMessage msg) { MockableCall call = new MockableCall(this, (IMethodCallMessage)msg); this.mocker.HandleCall(this, call); IMethodCallMessage mcm = msg as IMethodCallMessage; if (call.Exception != null) { return(new ReturnMessage(call.Exception, mcm)); } else if (call.IsConstructorCall) { return(EnterpriseServicesHelper.CreateConstructionReturnMessage((IConstructionCallMessage)msg, (MarshalByRefObject)this.GetTransparentProxy())); } else { return(new ReturnMessage(call.ReturnValue, call.Args, call.GetOutParameters().Length, mcm.LogicalCallContext, mcm)); } }
private IMethodReturnMessage InvokeOnServer(MockingProxy proxy, MockableCall call) { IMessage request = call.OriginalCall; IMethodCallMessage mcm = request as IMethodCallMessage; IConstructionCallMessage ccm = request as IConstructionCallMessage; if (ccm != null) { try { // Attach server instance: // (we do it only for MarshalByRefObjects as it's a requirement, don't really // know however what's the added value of attachingToServer... it also works // well without doing this) if (this.serverInstance is MarshalByRefObject) { proxy.AttachServer((MarshalByRefObject)this.serverInstance); } // Call instance constructor: RemotingServices.GetRealProxy(serverInstance).InitializeServerObject(ccm); // Build response: return(MockingTools.BuildReturnMessage(proxy.GetTransparentProxy(), ccm.Args, mcm)); } catch (Exception ex) { // Build response: return(MockingTools.BuildReturnMessage(ex, mcm)); } } else { try { // Invoke instance method: object[] args = new object[mcm.ArgCount]; mcm.Args.CopyTo(args, 0); object result = mcm.MethodBase.Invoke(serverInstance, args); // Build response: return(MockingTools.BuildReturnMessage(result, args, mcm)); } catch (TargetInvocationException ex) { // Build response: return(MockingTools.BuildReturnMessage(ex.InnerException, mcm)); } } }
public void HandleCall(MockingProxy proxy, MockableCall call) { if (call.IsConstructorCall) { call.SetConstructionResult("CurrencyMock"); } else { if (call.Method.Name.Equals("ConvertAmount")) { // Retrieve call args: decimal amount = (decimal)call.InArgs[0]; // Mock the call: call.SetCallResult(amount); } else { // Return from a void call: call.SetCallResult(); } } }
public void Serialization02Test() { // Create and initialize formatter: Sfmt.Binary.BinaryFormatter formatter = new Sfmt.Binary.BinaryFormatter(); formatter.AssemblyFormat = Sfmt.FormatterAssemblyStyle.Simple; // Create DS: global::System.Data.DataSet ds = new global::System.Data.DataSet(); global::System.Data.DataTable dt = ds.Tables.Add("SomeTable"); global::System.Data.DataColumn dc1 = dt.Columns.Add("ID", typeof(global::System.Int32)); ds.AcceptChanges(); // Create MockableCall: MockingProxy callee = new MockingProxy(typeof(Sample.FooBar), null, "m1"); MockableCall call = new MockableCall(callee, typeof(Sample.FooBar).GetMethod("SomeMethodWithInsAndOuts"), new object[] { 1, 2, null, 3 }); // Set dataset as callresult: call.SetCallResult(ds); Assert.IsNotNull(call.ReturnValue, "Test setup failure, test could not even be run !"); // Serialize call: MemoryStream buffer = new MemoryStream(); formatter.Serialize(buffer, call); // Reset buffer: buffer.Flush(); buffer.Position = 0; // Deserialize call: call = (MockableCall)formatter.Deserialize(buffer); // Verify results (expect returnValue to be non-null): Assert.IsNotNull(call); Assert.IsNotNull(call.ReturnValue, "ReturnValue is null, the old implementation issue has reoccured..."); Assert.IsTrue(call.ReturnValue is global::System.Data.DataSet, "What the heck ? returnValue should have been a dataset !"); }
/// <summary> /// Constructs a ReplayMockException for a given failed call. /// </summary> public ReplayMockException(MockableCall failedCall, string message) : base(message) { this.failedCall = failedCall; }
/// <summary> /// Plays back the given call. /// </summary> public static void PlayBackCall(MockableCall call) { recorder.PlayBackCall(call); }
/// <summary> /// Replays the expected call by returning the expected returnvalue. /// </summary> public override void Replay(MockableCall call) { base.Replay(call); call.SetCallResult(returnValue, outArgs); }
/// <summary> /// Plays back the given call. /// </summary> public static void PlayBackCall(MockableCall call) { recorder.PlayBackCall(call); }
/// <summary> /// Replays the expected call by throwing the exception. /// </summary> public override void Replay(MockableCall call) { base.Replay(call); call.SetExceptionResult(exception); }
/// <summary> /// Implements IMocker. /// </summary> public void HandleCall(MockingProxy proxy, MockableCall call) { try { IExpectedCall expectedCall = DequeueExpectedCall(); expectedCall.Replay(call); } catch (ArgumentOutOfRangeException) { throw new ReplayMockException(call, "Call not expected."); } }
/// <summary> /// Replays the expected call. /// </summary> public virtual void Replay(MockableCall call) { Validate(call); }
/// <summary> /// Handles the call by playing it back. /// </summary> public void HandleCall(MockingProxy proxy, MockableCall call) { RecorderManager.PlayBackCall(call); }
public void PlayBackCall(MockableCall actualCall) { MockableCall expectedCall = (MockableCall)this.records[this.pointer++]; Assert.AreEqual(expectedCall.MethodSignature, actualCall.MethodSignature); actualCall.SetResult(expectedCall); }
/// <summary> /// Process synchronous messages through the sink chain. Mocking can be applied here. /// </summary> public IMessage SyncProcessMessage(IMessage msg) { IMethodCallMessage mcm = (IMethodCallMessage)msg; IMethodReturnMessage result; if (RecorderManager.IsPlaying && RemotingMockService.IsUriToMock(mcm.Uri)) { MockingProxy proxy = new MockingProxy(Type.GetType(mcm.TypeName), new RemotingPlayBackMocker(), mcm.Uri); result = (IMethodReturnMessage)proxy.Invoke(msg); } else if (RecorderManager.IsRecording && !RecorderManager.IsInCall && RemotingMockService.IsUriToMock(mcm.Uri)) { MockingProxy proxy = new MockingProxy(Type.GetType(mcm.TypeName), null, mcm.Uri); MockableCall call = new MockableCall(proxy, mcm); using (new RecorderManager.Lock()) { result = SyncProcessMessageOnServer(mcm); call.SetResult(result); RecorderManager.RecordCall(call); } } else { result = (IMethodReturnMessage)nextMessageSink.SyncProcessMessage(msg); } return result; }
/// <summary> /// Process asynchronous messages through the sink chain. Mocking can be applied here. /// </summary> public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink) { if (RecorderManager.IsPlaying) { MockableCall call = new MockableCall(null, (IMethodCallMessage)msg); AsyncCallHandler handler = new AsyncCallHandler(replySink, call); RecorderManager.RecordCall(call); } else if (RecorderManager.IsRecording) { } else { return NextSink.AsyncProcessMessage(msg, replySink); } return nextMessageSink.AsyncProcessMessage( msg, new AsyncCallHandler( replySink, new MockableCall(null, (IMethodCallMessage)msg) ) ); }
public void Serialization05Test() { MemoryStream buffer = new MemoryStream(); Sfmt.Soap.SoapFormatter formatter = new Sfmt.Soap.SoapFormatter(); formatter.AssemblyFormat = Sfmt.FormatterAssemblyStyle.Simple; // Create some call: MockingProxy callee = new MockingProxy(typeof(Sample.FooBar), null, "m1"); MockableCall call = new MockableCall(callee, typeof(Sample.FooBar).GetMethod("SomeVoid"), new object[] { }); call.SetCallResult(); // Serialize it: formatter.Serialize(buffer, call); buffer.Flush(); // Deserialize it: buffer.Position = 0; MockableCall deserializedCall = (MockableCall)formatter.Deserialize(buffer); // Test result: Assert.IsNotNull(deserializedCall); Assert.IsFalse(deserializedCall.IsConstructorCall); Assert.IsNotNull(deserializedCall.Method); Assert.AreEqual("SomeVoid", deserializedCall.Method.Name); Assert.IsTrue(deserializedCall.ReturnValue == null); Assert.IsTrue(deserializedCall.IsCompleted); }
public void CreationTest() { MockingProxy callee = new MockingProxy(typeof(Sample.FooBar), null, "m1"); MockableCall call = new MockableCall(callee, typeof(Sample.FooBar).GetMethod("SomeMethodWithInsAndOuts"), new object[] { 1, 2, null, 3 }); }
public void Serialization04Test() { MemoryStream buffer = new MemoryStream(); Sfmt.Soap.SoapFormatter formatter = new Sfmt.Soap.SoapFormatter(); formatter.AssemblyFormat = Sfmt.FormatterAssemblyStyle.Simple; // Create some call: MockingProxy callee = new MockingProxy(typeof(Sample.FooBar), null, "m1"); MockableCall call = new MockableCall(callee, typeof(Sample.FooBar).GetMethod("IsItTrue"), new object[] { true }); call.SetCallResult(true); // Serialize it: formatter.Serialize(buffer, call); buffer.Flush(); // Deserialize it: buffer.Position = 0; MockableCall deserializedCall = (MockableCall)formatter.Deserialize(buffer); // Test result: Assert.IsNotNull(deserializedCall); Assert.IsFalse(deserializedCall.IsConstructorCall); Assert.IsNotNull(deserializedCall.Method); Assert.AreEqual("IsItTrue", deserializedCall.Method.Name); Assert.IsFalse(deserializedCall.ReturnValue is string, "ReturnValue of type bool was read back through soap serialization as a string."); Assert.IsTrue(deserializedCall.ReturnValue is bool); Assert.IsTrue(deserializedCall.InArgs[0] is bool); Assert.IsTrue((bool)deserializedCall.ReturnValue); Assert.IsTrue(deserializedCall.IsCompleted); }
/// <summary> /// Records the given call. /// </summary> public static void RecordCall(MockableCall call) { if (recordNestLevel == 1) { recorder.RecordCall(call); } else if (recordNestLevel == 0) { throw new InvalidOperationException("RecorderManager should be locked before recording a call."); } }
public void HandleCall(MockingProxy proxy, MockableCall call) { using (new RecorderManager.Lock()) { call.SetResult(InvokeOnServer(proxy, call)); RecorderManager.RecordCall(call); } }
/// <summary> /// Set the result of the call by copying the result of another call. /// </summary> public virtual void SetResult(MockableCall call) { if (call.Exception != null) { this.SetExceptionResult(call.Exception); } else if (this.IsConstructorCall) { this.SetConstructionResult(call.callee.InstanceName, call.OutArgs); } else { this.SetCallResult(call.ReturnValue, call.OutArgs); } }
/// <summary> /// Validates a call before replaying it. Checks that the call matches the expected /// call. If not so, raises a ReplayMockException. /// </summary> public virtual void Validate(MockableCall call) { if (!this.methodName.Equals(call.Method.Name)) throw new ReplayMockException(call, "Expected call name does not match received call.\r\nCall expected: " + methodName + "\r\nCall received: " + call.Method.Name); }
/// <summary> /// Constructs a ReplayMockException for a given failed call. /// </summary> public ReplayMockException(MockableCall failedCall, string message) : base(message) { this.failedCall = failedCall; }
public AsyncCallHandler(IMessageSink next, MockableCall call) { this.next = next; this.call = call; }
public void GetParametersTest() { // Create call: MockingProxy callee = new MockingProxy(typeof(Sample.FooBar), null, "m1"); MockableCall call = new MockableCall(callee, typeof(Sample.FooBar).GetMethod("SomeMethodWithInsAndOuts"), new object[] { 1, 2, null, 3 }); // Check parameters: Assert.AreEqual(3, call.GetInParameters().Length, "Input parameters count mismatch."); Assert.AreEqual(2, call.GetOutParameters().Length, "Output parameters count mismatch."); }
public void RecordCall(MockableCall call) { this.records.Add(call); }
public void IsInOutParameterTest() { // Create call: MockingProxy callee = new MockingProxy(typeof(Sample.FooBar), null, "m1"); MockableCall call = new MockableCall(callee, typeof(Sample.FooBar).GetMethod("SomeMethodWithInsAndOuts"), new object[] { 1, 2, null, 3 }); // Check in parameters: foreach (global::System.Reflection.ParameterInfo param in call.GetInParameters()) { Assert.IsTrue(call.IsParameterIn(param.Position)); } // Check out parameters: foreach (global::System.Reflection.ParameterInfo param in call.GetOutParameters()) { Assert.IsTrue(call.IsParameterOut(param.Position)); } // All params must be IN, OUT or IN/OUT: foreach (global::System.Reflection.ParameterInfo param in call.Method.GetParameters()) { Assert.IsTrue(call.IsParameterIn(param.Position) || call.IsParameterOut(param.Position)); } }
public void ScenarioPlayTest() { using (RecorderManager.NewRecordingSession("test")) { // Make a callee, not really used but needed to record a constructor call: MockingProxy callee = new MockingProxy(typeof(Sample.Account), null, "m1"); // Push some calls in the recorder: MockableCall lastcall; CurrentRecorder.RecordCall(lastcall = new MockableCall(callee, typeof(Sample.Account).GetConstructor(new Type[] { typeof(Sample.CurrencyUnit) }), null)); lastcall.SetConstructionResult("acc"); CurrentRecorder.RecordCall(lastcall = new MockableCall(callee, typeof(Sample.Account).GetMethod("Deposit"), null)); lastcall.SetCallResult(); CurrentRecorder.RecordCall(lastcall = new MockableCall(callee, typeof(Sample.Account).GetMethod("Withdraw"), null)); lastcall.SetCallResult(); CurrentRecorder.RecordCall(lastcall = new MockableCall(callee, typeof(Sample.Account).GetProperty("Balance").GetGetMethod(), null)); lastcall.SetCallResult(10m); } using (RecorderManager.NewPlayBackSession("test", true)) { // Register types to mock: MockService.AddTypeToMock(typeof(Sample.Account)); // Play scenario: Sample.Account acc = new Sample.Account(Sample.CurrencyUnit.EUR); acc.Deposit(100m); acc.Withdraw(25m); Decimal balance = acc.Balance; // Checks: Assert.AreEqual(10m, balance); // Does not match the scenario, but the mocking result ! } }
/// <summary> /// Replays the expected call and checks its arguments. /// </summary> public void Replay(MockableCall call) { // Check argument count: if (arguments.Length != call.Method.GetParameters().Length) { throw new ReplayMockException(call, "Call to method \"" + call.Method.Name + "\" expected wrong number of arguments."); } // Check arguments individually: int i = -1; foreach(System.Reflection.ParameterInfo pinfo in call.GetInParameters()) { i++; if (pinfo.IsOut) continue; // Skip output parameters if ((arguments[pinfo.Position] == null) && (call.InArgs[i] == null)) continue; // OK if both NULL if ((arguments[pinfo.Position] == null) || (call.InArgs[i] == null)) throw new ReplayMockException(call, "Argument \"" + pinfo.Name + "\" of method \"" + call.MethodSignature + "\" has a different value than expected."); if (arguments[pinfo.Position] is IExpectedValue) if ((arguments[pinfo.Position] as IExpectedValue).MatchesExpectation(call.InArgs[i])) continue; else throw new ReplayMockException(call, "Argument \"" + pinfo.Name + "\" of method \"" + call.MethodSignature + "\" has a different value than expected."); if (!arguments[pinfo.Position].Equals(call.InArgs[i])) throw new ReplayMockException(call, "Argument \"" + pinfo.Name + "\" of method \"" + call.MethodSignature + "\" has a different value than expected."); } // If all passed, replay the call: innerCall.Replay(call); }