I changed the api to sub.DoSomething().Returns(x => x.CallBase())
This commit is contained in:
Родитель
b3ae935769
Коммит
5de8edf0b5
|
@ -4,206 +4,230 @@ using NUnit.Framework;
|
|||
|
||||
namespace NSubstitute.Acceptance.Specs
|
||||
{
|
||||
// todo move tests to proper place, add more?
|
||||
public class CallBaseForMember
|
||||
{
|
||||
[Test]
|
||||
public void Given_SubstituteForInterface_When_MethodIsCalled_Then_ShouldThrowException()
|
||||
public class WhenCalledDoCallBase
|
||||
{
|
||||
var testAbstractClass = Substitute.For<ITestInterface>();
|
||||
Assert.Throws<CouldNotCallBaseException>(() => testAbstractClass.CallBaseFor().TestMethod());
|
||||
[Test]
|
||||
public void Given_SubstituteForInterface_When_MethodIsCalled_Then_ShouldThrowException()
|
||||
{
|
||||
var testInterface = Substitute.For<ITestInterface>();
|
||||
testInterface.When(x => x.VoidTestMethod()).Do(x => x.CallBase());
|
||||
Assert.Throws<CouldNotCallBaseException>(testInterface.VoidTestMethod);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForAbstractClass_When_AbstractMethodIsCalled_Then_ShouldThrowException()
|
||||
{
|
||||
var testAbstractClass = Substitute.For<TestAbstractClass>();
|
||||
testAbstractClass.When(x => x.VoidAbstractMethod()).Do(x => x.CallBase());
|
||||
Assert.Throws<CouldNotCallBaseException>(testAbstractClass.VoidAbstractMethod);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForAction_When_ActionIsCalled_Then_ShouldThrowException()
|
||||
{
|
||||
var action = Substitute.For<Action>();
|
||||
action.When(x => x.Invoke()).Do(x => x.CallBase());
|
||||
Assert.Throws<CouldNotCallBaseException>(() => action());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForFunc_When_FuncIsCalled_Then_ShouldThrowException()
|
||||
{
|
||||
var func = Substitute.For<Func<int>>();
|
||||
func.When(x => x.Invoke()).Do(x => x.CallBase());
|
||||
Assert.Throws<CouldNotCallBaseException>(() => func());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForEventHandler_When_EventHandlerIsCalled_Then_ShouldThrowException()
|
||||
{
|
||||
var eventHandler = Substitute.For<EventHandler>();
|
||||
eventHandler.When(x => x.Invoke(Arg.Any<object>(), Arg.Any<EventArgs>())).Do(x => x.CallBase());
|
||||
Assert.Throws<CouldNotCallBaseException>(() => eventHandler(null, null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForClass_When_VirtualMethodIsCalled_Then_ShouldCallBaseImplementation()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.When(x => x.VoidVirtualMethod()).Do(x => x.CallBase());
|
||||
testClass.VoidVirtualMethod();
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForClass_When_VirtualMethodIsSetup_ShouldNotCallRealImplementation()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.When(x => x.VoidVirtualMethod()).Do(x => x.CallBase());
|
||||
testClass.When(x => x.VoidVirtualMethod()).Do(x => x.CallBase());
|
||||
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForClass_When_VirtualMethodIsSetupTwice_Then_ShouldSetupCorrectly()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.When(x => x.VoidVirtualMethod()).Do(x => x.CallBase());
|
||||
testClass.When(x => x.VoidVirtualMethod()).Do(x => x.CallBase());
|
||||
|
||||
testClass.VoidVirtualMethod();
|
||||
// I doubt that we should call base implementation just once here
|
||||
// as .When().Do() syntax purpose is to invoke actions and not Return/Callbase
|
||||
// and just by accident we have two actions that call base implemenation
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForClass_When_AbstractMethodIsCalled_Then_ShouldCallBaseImplementation()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.When(x => x.VoidAbstractMethod()).Do(x => x.CallBase());
|
||||
testClass.VoidAbstractMethod();
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForClass_When_VirtualMethodIsCalledTwice_Then_ShouldCallBaseImplementationTwice()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.When(x => x.VoidVirtualMethod()).Do(x => x.CallBase());
|
||||
testClass.VoidVirtualMethod();
|
||||
testClass.VoidVirtualMethod();
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForAbstractClass_When_MethodWithImplementationIsCalled_Then_ShouldCallBaseImplementation()
|
||||
{
|
||||
var testAbstractClass = Substitute.For<TestAbstractClass>();
|
||||
testAbstractClass.When(x => x.MethodReturnsSameInt(Arg.Any<int>())).Do(x => x.CallBase());
|
||||
// .When().Do() syntax does not return value from base implementation
|
||||
Assert.That(testAbstractClass.MethodReturnsSameInt(1), Is.EqualTo(default(int)));
|
||||
// but it calls base implementation
|
||||
Assert.That(testAbstractClass.CalledTimes, Is.EqualTo(1));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForAbstractClass_When_AbstractMethodIsCalled_Then_ShouldThrowException()
|
||||
public class ReturnsCallBase
|
||||
{
|
||||
var testAbstractClass = Substitute.For<TestAbstractClass>();
|
||||
Assert.Throws<CouldNotCallBaseException>(() => testAbstractClass.CallBaseFor().AbstractMethod());
|
||||
}
|
||||
[Test]
|
||||
public void Given_SubstituteForInterface_When_MethodIsCalled_Then_ShouldThrowException()
|
||||
{
|
||||
var testInterface = Substitute.For<ITestInterface>();
|
||||
testInterface.TestMethodReturnsInt().Returns(x => x.CallBase());
|
||||
Assert.Throws<CouldNotCallBaseException>(() => testInterface.TestMethodReturnsInt());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForAction_When_ActionIsCalled_Then_ShouldThrowException()
|
||||
{
|
||||
var action = Substitute.For<Action>();
|
||||
Assert.Throws<CouldNotCallBaseException>(() => action.CallBaseFor().Invoke());
|
||||
}
|
||||
[Test]
|
||||
public void Given_SubstituteForAbstractClass_When_AbstractMethodIsCalled_Then_ShouldThrowException()
|
||||
{
|
||||
var testAbstractClass = Substitute.For<TestAbstractClass>();
|
||||
testAbstractClass.AbstractMethodReturnsSameInt(Arg.Any<int>()).Returns(x => x.CallBase());
|
||||
Assert.Throws<CouldNotCallBaseException>(() => testAbstractClass.AbstractMethodReturnsSameInt(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForFunc_When_FuncIsCalled_Then_ShouldThrowException()
|
||||
{
|
||||
var func = Substitute.For<Func<int>>();
|
||||
Assert.Throws<CouldNotCallBaseException>(() => func.CallBaseFor().Invoke());
|
||||
}
|
||||
[Test]
|
||||
public void Given_SubstituteForFunc_When_FuncIsCalled_Then_ShouldThrowException()
|
||||
{
|
||||
var func = Substitute.For<Func<int>>();
|
||||
func().Returns(x => x.CallBase());
|
||||
Assert.Throws<CouldNotCallBaseException>(() => func());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForEventHandler_When_EventHandlerIsCalled_Then_ShouldThrowException()
|
||||
{
|
||||
var eventHandler = Substitute.For<EventHandler>();
|
||||
Assert.Throws<CouldNotCallBaseException>(() =>
|
||||
eventHandler.CallBaseFor().Invoke(Arg.Any<object>(), Arg.Any<EventArgs>()));
|
||||
}
|
||||
[Test]
|
||||
public void Given_SubstituteForAbstractClass_When_MethodWithImplementationIsCalled_Then_ShouldCallBaseImplementation()
|
||||
{
|
||||
var testAbstractClass = Substitute.For<TestAbstractClass>();
|
||||
testAbstractClass.MethodReturnsSameInt(Arg.Any<int>()).Returns(x => x.CallBase());
|
||||
Assert.That(testAbstractClass.MethodReturnsSameInt(1), Is.EqualTo(1));
|
||||
Assert.That(testAbstractClass.CalledTimes, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void
|
||||
Given_SubstituteForAbstractClass_When_MethodWithImplementationIsCalled_Then_ShouldCallBaseImplementation
|
||||
()
|
||||
{
|
||||
var testAbstractClass = Substitute.For<TestAbstractClass>();
|
||||
testAbstractClass.CallBaseFor().MethodWithImplementation(Arg.Any<int>());
|
||||
Assert.That(testAbstractClass.MethodWithImplementation(1), Is.EqualTo(1));
|
||||
}
|
||||
[Test]
|
||||
[Ignore("Should/can we avoid call base here?")]
|
||||
public void
|
||||
Given_SubstituteForClass_When_VirtualMethodsReturnValueIsOverwritten_Then_ShouldNotCallBaseImplementation
|
||||
()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.VirtualMethodReturnsSameInt(Arg.Any<int>()).Returns(x => x.CallBase());
|
||||
testClass.VirtualMethodReturnsSameInt(Arg.Any<int>()).Returns(1);
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForClass_When_VirtualMethodIsCalled_Then_ShouldCallBaseImplementation()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.CallBaseFor().VirtualMethod();
|
||||
testClass.VirtualMethod();
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(1));
|
||||
}
|
||||
[Test]
|
||||
public void
|
||||
Given_SubstituteForClass_And_ReturnValueIsOverwritten_When_VirtualMethodIsCalled_Then_ShouldReturnOverwrittenValue
|
||||
()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.VirtualMethodReturnsSameInt(Arg.Any<int>()).Returns(x => x.CallBase());
|
||||
testClass.VirtualMethodReturnsSameInt(Arg.Any<int>()).Returns(2);
|
||||
Assert.That(testClass.VirtualMethodReturnsSameInt(1), Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForClass_When_CallBaseUsed_ShouldNotCallRealImplementation()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.CallBaseFor().VirtualMethod();
|
||||
testClass.CallBaseFor().VirtualMethod();
|
||||
[Test]
|
||||
public void
|
||||
Given_SubstituteForClass_And_VirtualMethodReturnsFuncs_When_VirtualMethodIsCalled_Then_ShouldReturnCorrectValues
|
||||
()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.VirtualMethodReturnsSameInt(Arg.Any<int>())
|
||||
.Returns(
|
||||
x => x.CallBase(),
|
||||
x => 1,
|
||||
x => { throw new Exception(); });
|
||||
Assert.That(testClass.VirtualMethodReturnsSameInt(2), Is.EqualTo(2));
|
||||
Assert.That(testClass.VirtualMethodReturnsSameInt(2), Is.EqualTo(1));
|
||||
Assert.Throws<Exception>(() => testClass.VirtualMethodReturnsSameInt(1));
|
||||
}
|
||||
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForClass_When_VirtualMethodIsSetupTwice_Then_ShouldSetupCorrectly()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.CallBaseFor().VirtualMethod();
|
||||
testClass.CallBaseFor().VirtualMethod();
|
||||
|
||||
testClass.VirtualMethod();
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForClass_When_AbstractMethodIsCalled_Then_ShouldCallBaseImplementation()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.CallBaseFor().AbstractMethod();
|
||||
testClass.AbstractMethod();
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_SubstituteForClass_When_VirtualMethodIsCalledTwice_Then_ShouldCallBaseImplementationTwice()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.CallBaseFor().VirtualMethod();
|
||||
testClass.VirtualMethod();
|
||||
testClass.VirtualMethod();
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void
|
||||
Given_SubstituteForClass_When_VirtualMethodsReturnValueIsOverwritten_Then_ShouldNotCallBaseImplementation
|
||||
()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.CallBaseFor().VirtualMethodReturnsSameInt(Arg.Any<int>());
|
||||
testClass.VirtualMethodReturnsSameInt(Arg.Any<int>()).Returns(1);
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void
|
||||
Given_SubstituteForClass_And_ReturnValueIsOverwritten_When_VirtualMethodIsCalled_Then_ShouldReturnOverwrittenValue
|
||||
()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.CallBaseFor().VirtualMethodReturnsSameInt(Arg.Any<int>());
|
||||
testClass.VirtualMethodReturnsSameInt(Arg.Any<int>()).Returns(2);
|
||||
Assert.That(testClass.VirtualMethodReturnsSameInt(1), Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void
|
||||
Given_SubstituteForClass_And_ObjectReturnValueIsOverwritten_When_VirtualMethodIsCalled_Then_ShouldReturnOverwrittenValue
|
||||
()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.CallBaseFor().VirtualMethodReturnsSameObject(Arg.Any<object>());
|
||||
var objectToReturn = new object();
|
||||
testClass.VirtualMethodReturnsSameObject(Arg.Any<object>()).Returns(objectToReturn);
|
||||
Assert.That(testClass.VirtualMethodReturnsSameObject(new object()), Is.EqualTo(objectToReturn));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void
|
||||
Given_SubstituteForClass_And_SubstituteDoesNotOverwriteReturn_When_VirtualMethodIsCalled_Then_ShouldCallBaseImplementation
|
||||
()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
var objectCallBase = new object();
|
||||
testClass.CallBaseFor().VirtualMethodReturnsSameObject(Arg.Is(objectCallBase));
|
||||
var objectCallSubstitute = new object();
|
||||
testClass.VirtualMethodReturnsSameObject(Arg.Is(objectCallSubstitute)).Returns(new object());
|
||||
Assert.That(testClass.VirtualMethodReturnsSameObject(objectCallBase), Is.EqualTo(objectCallBase));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void
|
||||
Given_SubstituteForClass_And_SubstituteDoesOverwriteReturn_When_VirtualMethodIsCalled_Then_ShouldReturnOverwrittenValue
|
||||
()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
var objectCallBase = new object();
|
||||
testClass.CallBaseFor().VirtualMethodReturnsSameObject(Arg.Is(objectCallBase));
|
||||
var objectToReturn = new object();
|
||||
testClass.VirtualMethodReturnsSameObject(Arg.Is(objectCallBase)).Returns(objectToReturn);
|
||||
Assert.That(testClass.VirtualMethodReturnsSameObject(objectCallBase), Is.EqualTo(objectToReturn));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void
|
||||
Given_SubstituteForClass_And_VirtualMethodReturnValueForSpecifiedArg_When_VirtualMethodIsCalledWithSpecifiedArg_Then_ShouldReturnOverwrittenValue
|
||||
()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.CallBaseFor().VirtualMethodReturnsSameInt(Arg.Any<int>());
|
||||
testClass.VirtualMethodReturnsSameInt(Arg.Is(1)).Returns(2);
|
||||
// substitute has higher priority than base implementation
|
||||
Assert.That(testClass.VirtualMethodReturnsSameInt(1), Is.EqualTo(2));
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void
|
||||
Given_SubstituteForClass_And_VirtualMethodReturnValueForSpecifiedArg_When_VirtualMethodIsCalledWithoutSpecifiedArg_Then_ShouldCallBaseImplementation
|
||||
()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.CallBaseFor().VirtualMethodReturnsSameInt(Arg.Any<int>());
|
||||
testClass.VirtualMethodReturnsSameInt(Arg.Is(1)).Returns(2);
|
||||
Assert.That(testClass.VirtualMethodReturnsSameInt(3), Is.EqualTo(3));
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(1));
|
||||
[Test]
|
||||
public void
|
||||
Given_SubstituteForClass_And_VirtualMethodReturnsFuncs_When_VirtualMethodIsCalled_Then_ShouldCallBaseCorrect
|
||||
()
|
||||
{
|
||||
var testClass = Substitute.For<TestClass>();
|
||||
testClass.VirtualMethodReturnsSameInt(Arg.Any<int>())
|
||||
.Returns(
|
||||
x => x.CallBase(),
|
||||
x => 1,
|
||||
x => 2);
|
||||
testClass.VirtualMethodReturnsSameInt(1);
|
||||
testClass.VirtualMethodReturnsSameInt(1);
|
||||
testClass.VirtualMethodReturnsSameInt(1);
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(1));
|
||||
}
|
||||
}
|
||||
|
||||
public interface ITestInterface
|
||||
{
|
||||
void TestMethod();
|
||||
void VoidTestMethod();
|
||||
int TestMethodReturnsInt();
|
||||
}
|
||||
|
||||
public abstract class TestAbstractClass
|
||||
{
|
||||
public abstract void AbstractMethod();
|
||||
public int CalledTimes { get; set; }
|
||||
|
||||
public virtual int MethodWithImplementation(int i)
|
||||
public abstract void VoidAbstractMethod();
|
||||
|
||||
public abstract int AbstractMethodReturnsSameInt(int i);
|
||||
|
||||
public virtual int MethodReturnsSameInt(int i)
|
||||
{
|
||||
CalledTimes++;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
public class TestClass : TestAbstractClass
|
||||
{
|
||||
public int CalledTimes { get; set; }
|
||||
|
||||
public virtual int VirtualMethodReturnsSameInt(int i)
|
||||
{
|
||||
|
@ -217,15 +241,21 @@ namespace NSubstitute.Acceptance.Specs
|
|||
return o;
|
||||
}
|
||||
|
||||
public virtual void VirtualMethod()
|
||||
public virtual void VoidVirtualMethod()
|
||||
{
|
||||
CalledTimes++;
|
||||
}
|
||||
|
||||
public override void AbstractMethod()
|
||||
public override void VoidAbstractMethod()
|
||||
{
|
||||
CalledTimes++;
|
||||
}
|
||||
|
||||
public override int AbstractMethodReturnsSameInt(int i)
|
||||
{
|
||||
CalledTimes++;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -189,7 +189,6 @@
|
|||
<Compile Include="Core\IReturn.cs" />
|
||||
<Compile Include="Core\PropertyCallFormatter.cs" />
|
||||
<Compile Include="Core\ReflectionExtensions.cs" />
|
||||
<Compile Include="Routing\Handlers\SetBaseForCallHandler.cs" />
|
||||
<Compile Include="Routing\IRouteFactory.cs" />
|
||||
<Compile Include="Routing\Route.cs" />
|
||||
<Compile Include="Exceptions\ArgumentNotFoundException.cs" />
|
||||
|
|
|
@ -10,22 +10,18 @@ namespace NSubstitute.Proxies.CastleDynamicProxy
|
|||
|
||||
public virtual ICall Map(IInvocation castleInvocation)
|
||||
{
|
||||
//Func<object> baseMethod = null;
|
||||
//if (castleInvocation.InvocationTarget != null &&
|
||||
// castleInvocation.MethodInvocationTarget.IsAbstract != true)
|
||||
//{
|
||||
// baseMethod = () =>
|
||||
// {
|
||||
// castleInvocation.Proceed();
|
||||
// return castleInvocation.ReturnValue;
|
||||
// };
|
||||
//}
|
||||
|
||||
Func<object> baseMethod = () =>
|
||||
Func<object> baseMethod = null;
|
||||
if (castleInvocation.InvocationTarget != null &&
|
||||
castleInvocation.MethodInvocationTarget.IsVirtual &&
|
||||
!castleInvocation.MethodInvocationTarget.IsAbstract &&
|
||||
!castleInvocation.MethodInvocationTarget.IsFinal)
|
||||
{
|
||||
baseMethod = () =>
|
||||
{
|
||||
castleInvocation.Proceed();
|
||||
return castleInvocation.ReturnValue;
|
||||
};
|
||||
}
|
||||
|
||||
return CallFactory.Create(castleInvocation.Method, castleInvocation.Arguments, castleInvocation.Proxy, baseMethod);
|
||||
}
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using NSubstitute.Core;
|
||||
using NSubstitute.Exceptions;
|
||||
|
||||
namespace NSubstitute.Routing.Handlers
|
||||
{
|
||||
public class SetBaseForCallHandler : ICallHandler
|
||||
{
|
||||
private readonly ICallSpecificationFactory _callSpecificationFactory;
|
||||
private readonly ICallResults _callResults;
|
||||
private readonly MatchArgs _matchArgs;
|
||||
|
||||
public SetBaseForCallHandler(ICallSpecificationFactory callSpecificationFactory, ICallResults callResults, MatchArgs matchArgs)
|
||||
{
|
||||
_callSpecificationFactory = callSpecificationFactory;
|
||||
_callResults = callResults;
|
||||
_matchArgs = matchArgs;
|
||||
}
|
||||
|
||||
public RouteAction Handle(ICall call)
|
||||
{
|
||||
var method = call.GetMethodInfo();
|
||||
if (!CanCallBase(method))
|
||||
{
|
||||
throw new CouldNotCallBaseException(method);
|
||||
}
|
||||
var callSpec = _callSpecificationFactory.CreateFrom(call, _matchArgs);
|
||||
_callResults.SetResult(callSpec, new ReturnValueFromBase(method.ReturnType));
|
||||
return RouteAction.Continue();
|
||||
}
|
||||
|
||||
private bool CanCallBase(MethodInfo methodInfo)
|
||||
{
|
||||
return methodInfo.IsVirtual && !methodInfo.IsFinal && !methodInfo.IsAbstract;
|
||||
}
|
||||
|
||||
class ReturnValueFromBase : IReturn
|
||||
{
|
||||
private readonly Type _expectedType;
|
||||
public ReturnValueFromBase(Type expectedType) { _expectedType = expectedType; }
|
||||
public object ReturnFor(CallInfo info) { return info.CallBase(); }
|
||||
public Type TypeOrNull() { return _expectedType; }
|
||||
public bool CanBeAssignedTo(Type t) { return _expectedType.IsAssignableFrom(t); }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ namespace NSubstitute.Routing
|
|||
{
|
||||
public interface IRouteFactory
|
||||
{
|
||||
IRoute CallBase(ISubstituteState state, MatchArgs matchArgs);
|
||||
IRoute CallQuery(ISubstituteState state);
|
||||
IRoute CheckReceivedCalls(ISubstituteState state, MatchArgs matchArgs, Quantity requiredQuantity);
|
||||
IRoute DoWhenCalled(ISubstituteState state, Action<CallInfo> doAction, MatchArgs matchArgs);
|
||||
|
|
|
@ -6,15 +6,6 @@ namespace NSubstitute.Routing
|
|||
{
|
||||
public class RouteFactory : IRouteFactory
|
||||
{
|
||||
public IRoute CallBase(ISubstituteState state, MatchArgs matchArgs)
|
||||
{
|
||||
return new Route(new ICallHandler[] {
|
||||
new ClearLastCallRouterHandler(state.SubstitutionContext)
|
||||
, new ClearUnusedCallSpecHandler(state)
|
||||
, new SetBaseForCallHandler(state.CallSpecificationFactory, state.CallResults, matchArgs)
|
||||
, ReturnDefaultForReturnTypeHandler()
|
||||
});
|
||||
}
|
||||
public IRoute CallQuery(ISubstituteState state)
|
||||
{
|
||||
return new Route(new ICallHandler[] {
|
||||
|
|
|
@ -224,26 +224,6 @@ namespace NSubstitute
|
|||
return GetRouterForSubstitute(substitute).ReceivedCalls();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls base implementation for the specified member called with any args.
|
||||
/// </summary>
|
||||
public static T CallBaseWithAnyArgsFor<T>(this T substitute) where T : class
|
||||
{
|
||||
var router = GetRouterForSubstitute(substitute);
|
||||
router.SetRoute(x => RouteFactory().CallBase(x, MatchArgs.Any));
|
||||
return substitute;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls base implementation for the specified member.
|
||||
/// </summary>
|
||||
public static T CallBaseFor<T>(this T substitute) where T : class
|
||||
{
|
||||
var router = GetRouterForSubstitute(substitute);
|
||||
router.SetRoute(x => RouteFactory().CallBase(x, MatchArgs.AsSpecifiedInCall));
|
||||
return substitute;
|
||||
}
|
||||
|
||||
private static ICallRouter GetRouterForSubstitute<T>(T substitute)
|
||||
{
|
||||
var context = SubstitutionContext.Current;
|
||||
|
|
Загрузка…
Ссылка в новой задаче