Throw on attempt to call base on non-virtual

Throwing CouldNotCallBaseException as soon as abstract/final member is
called.

Removing tests that attempt to configure non-virtual members.
This commit is contained in:
David Tchepak 2013-07-21 18:48:04 +10:00
Родитель 1f1fbe7ff5
Коммит a30ca18ea1
3 изменённых файлов: 33 добавлений и 31 удалений

Просмотреть файл

@ -10,40 +10,36 @@ namespace NSubstitute.Acceptance.Specs
public void Given_SubstituteForInterface_When_MethodIsCalled_Then_ShouldThrowException()
{
var testAbstractClass = Substitute.For<ITestInterface>();
testAbstractClass.CallBaseFor().TestMethod();
Assert.Throws<CouldNotCallBaseException>(testAbstractClass.TestMethod);
Assert.Throws<CouldNotCallBaseException>(() => testAbstractClass.CallBaseFor().TestMethod());
}
[Test]
public void Given_SubstituteForAbstractClass_When_AbstractMethodIsCalled_Then_ShouldThrowException()
{
var testAbstractClass = Substitute.For<TestAbstractClass>();
testAbstractClass.CallBaseFor().AbstractMethod();
Assert.Throws<CouldNotCallBaseException>(testAbstractClass.AbstractMethod);
Assert.Throws<CouldNotCallBaseException>(() => testAbstractClass.CallBaseFor().AbstractMethod());
}
[Test]
public void Given_SubstituteForAction_When_ActionIsCalled_Then_ShouldThrowException()
{
var action = Substitute.For<Action>();
action.CallBaseFor().Invoke();
Assert.Throws<CouldNotCallBaseException>(() => action());
Assert.Throws<CouldNotCallBaseException>(() => action.CallBaseFor().Invoke());
}
[Test]
public void Given_SubstituteForFunc_When_FuncIsCalled_Then_ShouldThrowException()
{
var func = Substitute.For<Func<int>>();
func.CallBaseFor().Invoke();
Assert.Throws<CouldNotCallBaseException>(() => func());
Assert.Throws<CouldNotCallBaseException>(() => func.CallBaseFor().Invoke());
}
[Test]
public void Given_SubstituteForEventHandler_When_EventHandlerIsCalled_Then_ShouldThrowException()
{
var eventHandler = Substitute.For<EventHandler>();
eventHandler.CallBaseFor().Invoke(Arg.Any<object>(), Arg.Any<EventArgs>());
Assert.Throws<CouldNotCallBaseException>(() => eventHandler.Invoke(null, null));
Assert.Throws<CouldNotCallBaseException>(() =>
eventHandler.CallBaseFor().Invoke(Arg.Any<object>(), Arg.Any<EventArgs>()));
}
[Test]
@ -65,12 +61,25 @@ namespace NSubstitute.Acceptance.Specs
Assert.That(testClass.CalledTimes, Is.EqualTo(1));
}
[Test]
public void Given_SubstituteForClass_When_CallBaseUsed_ShouldNotCallRealImplementation()
{
var testClass = Substitute.For<TestClass>();
testClass.CallBaseFor().VirtualMethod();
testClass.CallBaseFor().VirtualMethod();
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]
@ -82,17 +91,6 @@ namespace NSubstitute.Acceptance.Specs
Assert.That(testClass.CalledTimes, Is.EqualTo(1));
}
[Test]
public void
Given_SubstituteForClass_When_NotVirtualMethodIsSetup_And_NotVirtualMethodIsCalled_Then_ShouldCallBaseImplementationTwice
()
{
var testClass = Substitute.For<TestClass>();
testClass.CallBaseFor().NotVirtualMethodReturnsSameInt(Arg.Any<int>());
testClass.NotVirtualMethodReturnsSameInt(1);
Assert.That(testClass.CalledTimes, Is.EqualTo(2));
}
[Test]
public void Given_SubstituteForClass_When_VirtualMethodIsCalledTwice_Then_ShouldCallBaseImplementationTwice()
{
@ -126,8 +124,6 @@ namespace NSubstitute.Acceptance.Specs
}
[Test]
[Pending, Explicit]
// test fails only when executed with all tests, don't understand why by now.
public void
Given_SubstituteForClass_And_ObjectReturnValueIsOverwritten_When_VirtualMethodIsCalled_Then_ShouldReturnOverwrittenValue
()
@ -199,7 +195,7 @@ namespace NSubstitute.Acceptance.Specs
{
public abstract void AbstractMethod();
public int MethodWithImplementation(int i)
public virtual int MethodWithImplementation(int i)
{
return i;
}
@ -226,12 +222,6 @@ namespace NSubstitute.Acceptance.Specs
CalledTimes++;
}
public int NotVirtualMethodReturnsSameInt(int i)
{
CalledTimes++;
return i;
}
public override void AbstractMethod()
{
CalledTimes++;

Просмотреть файл

@ -1,4 +1,7 @@
using System;
using System.Reflection;
using NSubstitute.Core;
using NSubstitute.Exceptions;
namespace NSubstitute.Routing.Handlers
{
@ -17,9 +20,19 @@ namespace NSubstitute.Routing.Handlers
public RouteAction Handle(ICall call)
{
var method = call.GetMethodInfo();
if (!CanCallBase(method))
{
throw new CouldNotCallBaseException(method);
}
var callSpec = _callSpecificationFactory.CreateFrom(call, _matchArgs);
_callBaseSpecifications.Add(callSpec);
return RouteAction.Continue();
}
private bool CanCallBase(MethodInfo methodInfo)
{
return methodInfo.IsVirtual && !methodInfo.IsFinal && !methodInfo.IsAbstract;
}
}
}

Просмотреть файл

@ -15,7 +15,6 @@ namespace NSubstitute.Routing
, ReturnDefaultForReturnTypeHandler()
});
}
public IRoute CallQuery(ISubstituteState state)
{
return new Route(new ICallHandler[] {