Ensuring base method is only evaluated once per call

This commit is contained in:
David Tchepak 2013-07-22 19:51:43 +10:00
Родитель 5de8edf0b5
Коммит abee0831d7
2 изменённых файлов: 20 добавлений и 20 удалений

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

@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
using NSubstitute.Exceptions;
using NUnit.Framework;
namespace NSubstitute.Acceptance.Specs
{
// todo move tests to proper place, add more?
public class CallBaseForMember
{
public class WhenCalledDoCallBase
@ -68,20 +68,6 @@ namespace NSubstitute.Acceptance.Specs
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()
{
@ -111,6 +97,22 @@ namespace NSubstitute.Acceptance.Specs
// but it calls base implementation
Assert.That(testAbstractClass.CalledTimes, Is.EqualTo(1));
}
[Test]
public void OnlyCallBaseOncePerCall()
{
var sub = Substitute.For<TestAbstractClass>();
var list = new List<int>();
sub.MethodReturnsSameInt(Arg.Any<int>()).Returns(x => x.CallBase());
sub.When(x => x.MethodReturnsSameInt(Arg.Any<int>())).Do(x => list.Add((int) x.CallBase()));
sub.When(x => x.MethodReturnsSameInt(Arg.Any<int>())).Do(x => list.Add((int) x.CallBase()));
sub.MethodReturnsSameInt(10);
//Actions still performed twice, but base only called once
Assert.That(list, Is.EquivalentTo(new[] {10, 10}));
Assert.That(sub.CalledTimes, Is.EqualTo(1));
}
}
public class ReturnsCallBase

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

@ -16,11 +16,9 @@ namespace NSubstitute.Proxies.CastleDynamicProxy
!castleInvocation.MethodInvocationTarget.IsAbstract &&
!castleInvocation.MethodInvocationTarget.IsFinal)
{
baseMethod = () =>
{
castleInvocation.Proceed();
return castleInvocation.ReturnValue;
};
Func<object> baseResult = () => { castleInvocation.Proceed(); return castleInvocation.ReturnValue; };
var result = new Lazy<object>(baseResult);
baseMethod = () => result.Value;
}
return CallFactory.Create(castleInvocation.Method, castleInvocation.Arguments, castleInvocation.Proxy, baseMethod);