Adding call base exclusions (When..DoNotCallBase)
This commit is contained in:
Родитель
d426c93754
Коммит
5e34e1b701
|
@ -1,7 +1,5 @@
|
||||||
using System.Collections;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NSubstitute.Acceptance.Specs.Infrastructure;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace NSubstitute.Acceptance.Specs
|
namespace NSubstitute.Acceptance.Specs
|
||||||
|
|
|
@ -69,8 +69,9 @@ namespace NSubstitute.Acceptance.Specs
|
||||||
var wasCalled = false;
|
var wasCalled = false;
|
||||||
var testClass = Substitute.ForPartsOf<TestClass>();
|
var testClass = Substitute.ForPartsOf<TestClass>();
|
||||||
testClass.When(x => x.VoidAbstractMethod())
|
testClass.When(x => x.VoidAbstractMethod())
|
||||||
.DoNotCallBase()
|
|
||||||
.Do(x => wasCalled = true);
|
.Do(x => wasCalled = true);
|
||||||
|
testClass.When(x => x.VoidAbstractMethod())
|
||||||
|
.DoNotCallBase();
|
||||||
testClass.VoidAbstractMethod();
|
testClass.VoidAbstractMethod();
|
||||||
Assert.That(testClass.CalledTimes, Is.EqualTo(0));
|
Assert.That(testClass.CalledTimes, Is.EqualTo(0));
|
||||||
Assert.That(wasCalled);
|
Assert.That(wasCalled);
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
using NSubstitute.Core;
|
||||||
|
using NSubstitute.Specs.Infrastructure;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace NSubstitute.Specs
|
||||||
|
{
|
||||||
|
public class CallBaseExclusionsSpecs : ConcernFor<CallBaseExclusions>
|
||||||
|
{
|
||||||
|
public override CallBaseExclusions CreateSubjectUnderTest() { return new CallBaseExclusions(); }
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Exclude_call()
|
||||||
|
{
|
||||||
|
var call = mock<ICall>();
|
||||||
|
var spec = mock<ICallSpecification>();
|
||||||
|
spec.stub(x => x.IsSatisfiedBy(call)).Return(true);
|
||||||
|
sut.Exclude(spec);
|
||||||
|
|
||||||
|
Assert.That(sut.IsExcluded(call), Is.True);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Non_excluded_call()
|
||||||
|
{
|
||||||
|
var call = mock<ICall>();
|
||||||
|
|
||||||
|
Assert.That(sut.IsExcluded(call), Is.False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -90,6 +90,7 @@
|
||||||
<Compile Include="Arguments\NonParamsArgumentSpecificationFactorySpecs.cs" />
|
<Compile Include="Arguments\NonParamsArgumentSpecificationFactorySpecs.cs" />
|
||||||
<Compile Include="Arguments\ParamsArgumentSpecificationFactorySpecs.cs" />
|
<Compile Include="Arguments\ParamsArgumentSpecificationFactorySpecs.cs" />
|
||||||
<Compile Include="CallActionsSpecs.cs" />
|
<Compile Include="CallActionsSpecs.cs" />
|
||||||
|
<Compile Include="CallBaseExclusionsSpecs.cs" />
|
||||||
<Compile Include="CallFactorySpecs.cs" />
|
<Compile Include="CallFactorySpecs.cs" />
|
||||||
<Compile Include="CallFormatterSpecs.cs" />
|
<Compile Include="CallFormatterSpecs.cs" />
|
||||||
<Compile Include="CallInfoFactorySpecs.cs" />
|
<Compile Include="CallInfoFactorySpecs.cs" />
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace NSubstitute.Core
|
||||||
|
{
|
||||||
|
public class CallBaseExclusions : ICallBaseExclusions
|
||||||
|
{
|
||||||
|
readonly List<ICallSpecification> _excludedCallSpecs = new List<ICallSpecification>();
|
||||||
|
|
||||||
|
public void Exclude(ICallSpecification callSpecification)
|
||||||
|
{
|
||||||
|
_excludedCallSpecs.Add(callSpecification);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsExcluded(ICall callInfo)
|
||||||
|
{
|
||||||
|
return _excludedCallSpecs.Any(cs => cs.IsSatisfiedBy(callInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
namespace NSubstitute.Core
|
||||||
|
{
|
||||||
|
public interface ICallBaseExclusions
|
||||||
|
{
|
||||||
|
void Exclude(ICallSpecification callSpecification);
|
||||||
|
bool IsExcluded(ICall callInfo);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ namespace NSubstitute.Core
|
||||||
IConfigureCall ConfigureCall { get; }
|
IConfigureCall ConfigureCall { get; }
|
||||||
IEventHandlerRegistry EventHandlerRegistry { get; }
|
IEventHandlerRegistry EventHandlerRegistry { get; }
|
||||||
IAutoValueProvider[] AutoValueProviders { get; }
|
IAutoValueProvider[] AutoValueProviders { get; }
|
||||||
|
ICallBaseExclusions CallBaseExclusions { get; }
|
||||||
void ClearUnusedCallSpecs();
|
void ClearUnusedCallSpecs();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@ namespace NSubstitute.Core
|
||||||
public ICallResults CallResults { get; private set; }
|
public ICallResults CallResults { get; private set; }
|
||||||
public ICallSpecificationFactory CallSpecificationFactory { get; private set; }
|
public ICallSpecificationFactory CallSpecificationFactory { get; private set; }
|
||||||
public ICallActions CallActions { get; private set; }
|
public ICallActions CallActions { get; private set; }
|
||||||
|
public ICallBaseExclusions CallBaseExclusions { get; private set; }
|
||||||
public bool CallBaseByDefault { get; set; }
|
public bool CallBaseByDefault { get; set; }
|
||||||
public SequenceNumberGenerator SequenceNumberGenerator { get; private set; }
|
public SequenceNumberGenerator SequenceNumberGenerator { get; private set; }
|
||||||
public IConfigureCall ConfigureCall { get; private set; }
|
public IConfigureCall ConfigureCall { get; private set; }
|
||||||
|
@ -31,6 +32,7 @@ namespace NSubstitute.Core
|
||||||
CallResults = new CallResults(callInfoFactory);
|
CallResults = new CallResults(callInfoFactory);
|
||||||
CallSpecificationFactory = CallSpecificationFactoryFactoryYesThatsRight.CreateCallSpecFactory();
|
CallSpecificationFactory = CallSpecificationFactoryFactoryYesThatsRight.CreateCallSpecFactory();
|
||||||
CallActions = new CallActions(callInfoFactory);
|
CallActions = new CallActions(callInfoFactory);
|
||||||
|
CallBaseExclusions = new CallBaseExclusions();
|
||||||
|
|
||||||
var getCallSpec = new GetCallSpec(callStack, PendingSpecification, CallSpecificationFactory, CallActions);
|
var getCallSpec = new GetCallSpec(callStack, PendingSpecification, CallSpecificationFactory, CallActions);
|
||||||
|
|
||||||
|
@ -50,6 +52,5 @@ namespace NSubstitute.Core
|
||||||
{
|
{
|
||||||
PendingSpecification.Clear();
|
PendingSpecification.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,10 +30,13 @@ namespace NSubstitute.Core
|
||||||
_call(_substitute);
|
_call(_substitute);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WhenCalled<T> DoNotCallBase()
|
/// <summary>
|
||||||
|
/// Do not call the base implementation on future calls. For us with partial substitutes.
|
||||||
|
/// </summary>
|
||||||
|
public void DoNotCallBase()
|
||||||
{
|
{
|
||||||
//TODO: stop this call from going through to base
|
_callRouter.SetRoute(x => _routeFactory.DoNotCallBase(x, _matchArgs));
|
||||||
return this;
|
_call(_substitute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -115,6 +115,7 @@
|
||||||
<Compile Include="Core\Arguments\ParamsArgumentSpecificationFactory.cs" />
|
<Compile Include="Core\Arguments\ParamsArgumentSpecificationFactory.cs" />
|
||||||
<Compile Include="Core\Arguments\SuppliedArgumentSpecifications.cs" />
|
<Compile Include="Core\Arguments\SuppliedArgumentSpecifications.cs" />
|
||||||
<Compile Include="Core\Arguments\SuppliedArgumentSpecificationsFactory.cs" />
|
<Compile Include="Core\Arguments\SuppliedArgumentSpecificationsFactory.cs" />
|
||||||
|
<Compile Include="Core\CallBaseExclusions.cs" />
|
||||||
<Compile Include="Core\CallFactory.cs" />
|
<Compile Include="Core\CallFactory.cs" />
|
||||||
<Compile Include="Core\CallSpecAndTarget.cs" />
|
<Compile Include="Core\CallSpecAndTarget.cs" />
|
||||||
<Compile Include="Core\CallSpecificationFactoryFactoryYesThatsRight.cs" />
|
<Compile Include="Core\CallSpecificationFactoryFactoryYesThatsRight.cs" />
|
||||||
|
@ -124,6 +125,7 @@
|
||||||
<Compile Include="Core\Arguments\IArgumentEqualsSpecificationFactory.cs" />
|
<Compile Include="Core\Arguments\IArgumentEqualsSpecificationFactory.cs" />
|
||||||
<Compile Include="Core\Extensions.cs" />
|
<Compile Include="Core\Extensions.cs" />
|
||||||
<Compile Include="Core\GetCallSpec.cs" />
|
<Compile Include="Core\GetCallSpec.cs" />
|
||||||
|
<Compile Include="Core\ICallBaseExclusions.cs" />
|
||||||
<Compile Include="Core\ICallRouterProvider.cs" />
|
<Compile Include="Core\ICallRouterProvider.cs" />
|
||||||
<Compile Include="Core\IGetCallSpec.cs" />
|
<Compile Include="Core\IGetCallSpec.cs" />
|
||||||
<Compile Include="Core\Maybe.cs" />
|
<Compile Include="Core\Maybe.cs" />
|
||||||
|
@ -169,6 +171,7 @@
|
||||||
<Compile Include="Routing\Handlers\AddCallToQueryResultHandler.cs" />
|
<Compile Include="Routing\Handlers\AddCallToQueryResultHandler.cs" />
|
||||||
<Compile Include="Routing\Handlers\ClearLastCallRouterHandler.cs" />
|
<Compile Include="Routing\Handlers\ClearLastCallRouterHandler.cs" />
|
||||||
<Compile Include="Routing\Handlers\ClearUnusedCallSpecHandler.cs" />
|
<Compile Include="Routing\Handlers\ClearUnusedCallSpecHandler.cs" />
|
||||||
|
<Compile Include="Routing\Handlers\DoNotCallBaseForCallHandler.cs" />
|
||||||
<Compile Include="Routing\Handlers\ReturnAutoValueForThisAndSubsequentCallsHandler.cs" />
|
<Compile Include="Routing\Handlers\ReturnAutoValueForThisAndSubsequentCallsHandler.cs" />
|
||||||
<Compile Include="Routing\Handlers\RecordCallSpecificationHandler.cs" />
|
<Compile Include="Routing\Handlers\RecordCallSpecificationHandler.cs" />
|
||||||
<Compile Include="Core\MatchArgs.cs" />
|
<Compile Include="Core\MatchArgs.cs" />
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
using NSubstitute.Core;
|
||||||
|
|
||||||
|
namespace NSubstitute.Routing.Handlers
|
||||||
|
{
|
||||||
|
public class DoNotCallBaseForCallHandler :ICallHandler
|
||||||
|
{
|
||||||
|
private readonly ICallSpecificationFactory _callSpecificationFactory;
|
||||||
|
private readonly ICallBaseExclusions _exclusions;
|
||||||
|
private readonly MatchArgs _matchArgs;
|
||||||
|
|
||||||
|
public DoNotCallBaseForCallHandler(ICallSpecificationFactory callSpecificationFactory, ICallBaseExclusions exclusions, MatchArgs matchArgs)
|
||||||
|
{
|
||||||
|
_callSpecificationFactory = callSpecificationFactory;
|
||||||
|
_exclusions = exclusions;
|
||||||
|
_matchArgs = matchArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteAction Handle(ICall call)
|
||||||
|
{
|
||||||
|
var callSpec = _callSpecificationFactory.CreateFrom(call, _matchArgs);
|
||||||
|
_exclusions.Exclude(callSpec);
|
||||||
|
return RouteAction.Continue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,15 +5,18 @@ namespace NSubstitute.Routing.Handlers
|
||||||
public class ReturnFromBaseIfRequired : ICallHandler
|
public class ReturnFromBaseIfRequired : ICallHandler
|
||||||
{
|
{
|
||||||
private readonly bool _required;
|
private readonly bool _required;
|
||||||
|
private readonly ICallBaseExclusions _callBaseExclusions;
|
||||||
|
|
||||||
public ReturnFromBaseIfRequired(bool required)
|
public ReturnFromBaseIfRequired(bool required, ICallBaseExclusions callBaseExclusions)
|
||||||
{
|
{
|
||||||
_required = required;
|
_required = required;
|
||||||
|
_callBaseExclusions = callBaseExclusions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RouteAction Handle(ICall call)
|
public RouteAction Handle(ICall call)
|
||||||
{
|
{
|
||||||
if (!_required) return RouteAction.Continue();
|
if (!_required) return RouteAction.Continue();
|
||||||
|
if (_callBaseExclusions.IsExcluded(call)) return RouteAction.Continue();
|
||||||
|
|
||||||
return call
|
return call
|
||||||
.TryCallBase()
|
.TryCallBase()
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace NSubstitute.Routing
|
||||||
IRoute CallQuery(ISubstituteState state);
|
IRoute CallQuery(ISubstituteState state);
|
||||||
IRoute CheckReceivedCalls(ISubstituteState state, MatchArgs matchArgs, Quantity requiredQuantity);
|
IRoute CheckReceivedCalls(ISubstituteState state, MatchArgs matchArgs, Quantity requiredQuantity);
|
||||||
IRoute DoWhenCalled(ISubstituteState state, Action<CallInfo> doAction, MatchArgs matchArgs);
|
IRoute DoWhenCalled(ISubstituteState state, Action<CallInfo> doAction, MatchArgs matchArgs);
|
||||||
|
IRoute DoNotCallBase(ISubstituteState state, MatchArgs matchArgs);
|
||||||
IRoute RaiseEvent(ISubstituteState state, Func<ICall, object[]> getEventArguments);
|
IRoute RaiseEvent(ISubstituteState state, Func<ICall, object[]> getEventArguments);
|
||||||
IRoute RecordCallSpecification(ISubstituteState state);
|
IRoute RecordCallSpecification(ISubstituteState state);
|
||||||
IRoute RecordReplay(ISubstituteState state);
|
IRoute RecordReplay(ISubstituteState state);
|
||||||
|
|
|
@ -34,6 +34,15 @@ namespace NSubstitute.Routing
|
||||||
, ReturnDefaultForReturnTypeHandler()
|
, ReturnDefaultForReturnTypeHandler()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
public IRoute DoNotCallBase(ISubstituteState state, MatchArgs matchArgs)
|
||||||
|
{
|
||||||
|
return new Route(new ICallHandler[] {
|
||||||
|
new ClearLastCallRouterHandler(state.SubstitutionContext)
|
||||||
|
, new ClearUnusedCallSpecHandler(state)
|
||||||
|
, new DoNotCallBaseForCallHandler(state.CallSpecificationFactory, state.CallBaseExclusions, matchArgs)
|
||||||
|
, ReturnDefaultForReturnTypeHandler()
|
||||||
|
});
|
||||||
|
}
|
||||||
public IRoute RaiseEvent(ISubstituteState state, Func<ICall, object[]> getEventArguments)
|
public IRoute RaiseEvent(ISubstituteState state, Func<ICall, object[]> getEventArguments)
|
||||||
{
|
{
|
||||||
return new Route(new ICallHandler[] {
|
return new Route(new ICallHandler[] {
|
||||||
|
@ -62,7 +71,7 @@ namespace NSubstitute.Routing
|
||||||
, new PropertySetterHandler(new PropertyHelper(), state.ConfigureCall)
|
, new PropertySetterHandler(new PropertyHelper(), state.ConfigureCall)
|
||||||
, new DoActionsCallHandler(state.CallActions)
|
, new DoActionsCallHandler(state.CallActions)
|
||||||
, new ReturnConfiguredResultHandler(state.CallResults)
|
, new ReturnConfiguredResultHandler(state.CallResults)
|
||||||
, new ReturnFromBaseIfRequired(state.CallBaseByDefault)
|
, new ReturnFromBaseIfRequired(state.CallBaseByDefault, state.CallBaseExclusions)
|
||||||
, new ReturnAutoValueForThisAndSubsequentCallsHandler(state.AutoValueProviders, state.ConfigureCall)
|
, new ReturnAutoValueForThisAndSubsequentCallsHandler(state.AutoValueProviders, state.ConfigureCall)
|
||||||
, ReturnDefaultForReturnTypeHandler()
|
, ReturnDefaultForReturnTypeHandler()
|
||||||
});
|
});
|
||||||
|
|
Загрузка…
Ссылка в новой задаче