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 NSubstitute.Acceptance.Specs.Infrastructure;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace NSubstitute.Acceptance.Specs
|
||||
|
|
|
@ -69,8 +69,9 @@ namespace NSubstitute.Acceptance.Specs
|
|||
var wasCalled = false;
|
||||
var testClass = Substitute.ForPartsOf<TestClass>();
|
||||
testClass.When(x => x.VoidAbstractMethod())
|
||||
.DoNotCallBase()
|
||||
.Do(x => wasCalled = true);
|
||||
testClass.When(x => x.VoidAbstractMethod())
|
||||
.DoNotCallBase();
|
||||
testClass.VoidAbstractMethod();
|
||||
Assert.That(testClass.CalledTimes, Is.EqualTo(0));
|
||||
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\ParamsArgumentSpecificationFactorySpecs.cs" />
|
||||
<Compile Include="CallActionsSpecs.cs" />
|
||||
<Compile Include="CallBaseExclusionsSpecs.cs" />
|
||||
<Compile Include="CallFactorySpecs.cs" />
|
||||
<Compile Include="CallFormatterSpecs.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; }
|
||||
IEventHandlerRegistry EventHandlerRegistry { get; }
|
||||
IAutoValueProvider[] AutoValueProviders { get; }
|
||||
ICallBaseExclusions CallBaseExclusions { get; }
|
||||
void ClearUnusedCallSpecs();
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ namespace NSubstitute.Core
|
|||
public ICallResults CallResults { get; private set; }
|
||||
public ICallSpecificationFactory CallSpecificationFactory { get; private set; }
|
||||
public ICallActions CallActions { get; private set; }
|
||||
public ICallBaseExclusions CallBaseExclusions { get; private set; }
|
||||
public bool CallBaseByDefault { get; set; }
|
||||
public SequenceNumberGenerator SequenceNumberGenerator { get; private set; }
|
||||
public IConfigureCall ConfigureCall { get; private set; }
|
||||
|
@ -31,6 +32,7 @@ namespace NSubstitute.Core
|
|||
CallResults = new CallResults(callInfoFactory);
|
||||
CallSpecificationFactory = CallSpecificationFactoryFactoryYesThatsRight.CreateCallSpecFactory();
|
||||
CallActions = new CallActions(callInfoFactory);
|
||||
CallBaseExclusions = new CallBaseExclusions();
|
||||
|
||||
var getCallSpec = new GetCallSpec(callStack, PendingSpecification, CallSpecificationFactory, CallActions);
|
||||
|
||||
|
@ -50,6 +52,5 @@ namespace NSubstitute.Core
|
|||
{
|
||||
PendingSpecification.Clear();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,10 +30,13 @@ namespace NSubstitute.Core
|
|||
_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
|
||||
return this;
|
||||
_callRouter.SetRoute(x => _routeFactory.DoNotCallBase(x, _matchArgs));
|
||||
_call(_substitute);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -115,6 +115,7 @@
|
|||
<Compile Include="Core\Arguments\ParamsArgumentSpecificationFactory.cs" />
|
||||
<Compile Include="Core\Arguments\SuppliedArgumentSpecifications.cs" />
|
||||
<Compile Include="Core\Arguments\SuppliedArgumentSpecificationsFactory.cs" />
|
||||
<Compile Include="Core\CallBaseExclusions.cs" />
|
||||
<Compile Include="Core\CallFactory.cs" />
|
||||
<Compile Include="Core\CallSpecAndTarget.cs" />
|
||||
<Compile Include="Core\CallSpecificationFactoryFactoryYesThatsRight.cs" />
|
||||
|
@ -124,6 +125,7 @@
|
|||
<Compile Include="Core\Arguments\IArgumentEqualsSpecificationFactory.cs" />
|
||||
<Compile Include="Core\Extensions.cs" />
|
||||
<Compile Include="Core\GetCallSpec.cs" />
|
||||
<Compile Include="Core\ICallBaseExclusions.cs" />
|
||||
<Compile Include="Core\ICallRouterProvider.cs" />
|
||||
<Compile Include="Core\IGetCallSpec.cs" />
|
||||
<Compile Include="Core\Maybe.cs" />
|
||||
|
@ -169,6 +171,7 @@
|
|||
<Compile Include="Routing\Handlers\AddCallToQueryResultHandler.cs" />
|
||||
<Compile Include="Routing\Handlers\ClearLastCallRouterHandler.cs" />
|
||||
<Compile Include="Routing\Handlers\ClearUnusedCallSpecHandler.cs" />
|
||||
<Compile Include="Routing\Handlers\DoNotCallBaseForCallHandler.cs" />
|
||||
<Compile Include="Routing\Handlers\ReturnAutoValueForThisAndSubsequentCallsHandler.cs" />
|
||||
<Compile Include="Routing\Handlers\RecordCallSpecificationHandler.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
|
||||
{
|
||||
private readonly bool _required;
|
||||
private readonly ICallBaseExclusions _callBaseExclusions;
|
||||
|
||||
public ReturnFromBaseIfRequired(bool required)
|
||||
public ReturnFromBaseIfRequired(bool required, ICallBaseExclusions callBaseExclusions)
|
||||
{
|
||||
_required = required;
|
||||
_callBaseExclusions = callBaseExclusions;
|
||||
}
|
||||
|
||||
public RouteAction Handle(ICall call)
|
||||
{
|
||||
if (!_required) return RouteAction.Continue();
|
||||
if (_callBaseExclusions.IsExcluded(call)) return RouteAction.Continue();
|
||||
|
||||
return call
|
||||
.TryCallBase()
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace NSubstitute.Routing
|
|||
IRoute CallQuery(ISubstituteState state);
|
||||
IRoute CheckReceivedCalls(ISubstituteState state, MatchArgs matchArgs, Quantity requiredQuantity);
|
||||
IRoute DoWhenCalled(ISubstituteState state, Action<CallInfo> doAction, MatchArgs matchArgs);
|
||||
IRoute DoNotCallBase(ISubstituteState state, MatchArgs matchArgs);
|
||||
IRoute RaiseEvent(ISubstituteState state, Func<ICall, object[]> getEventArguments);
|
||||
IRoute RecordCallSpecification(ISubstituteState state);
|
||||
IRoute RecordReplay(ISubstituteState state);
|
||||
|
|
|
@ -34,6 +34,15 @@ namespace NSubstitute.Routing
|
|||
, 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)
|
||||
{
|
||||
return new Route(new ICallHandler[] {
|
||||
|
@ -62,7 +71,7 @@ namespace NSubstitute.Routing
|
|||
, new PropertySetterHandler(new PropertyHelper(), state.ConfigureCall)
|
||||
, new DoActionsCallHandler(state.CallActions)
|
||||
, new ReturnConfiguredResultHandler(state.CallResults)
|
||||
, new ReturnFromBaseIfRequired(state.CallBaseByDefault)
|
||||
, new ReturnFromBaseIfRequired(state.CallBaseByDefault, state.CallBaseExclusions)
|
||||
, new ReturnAutoValueForThisAndSubsequentCallsHandler(state.AutoValueProviders, state.ConfigureCall)
|
||||
, ReturnDefaultForReturnTypeHandler()
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче