In progress, removing CallBase()
This commit is contained in:
Родитель
33679acfdd
Коммит
d426c93754
|
@ -1,263 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NSubstitute.Exceptions;
|
|
||||||
using NUnit.Framework;
|
|
||||||
|
|
||||||
namespace NSubstitute.Acceptance.Specs
|
|
||||||
{
|
|
||||||
public class CallBaseForMember
|
|
||||||
{
|
|
||||||
public class WhenCalledDoCallBase
|
|
||||||
{
|
|
||||||
[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_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 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
|
|
||||||
{
|
|
||||||
[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_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>>();
|
|
||||||
func().Returns(x => x.CallBase());
|
|
||||||
Assert.Throws<CouldNotCallBaseException>(() => func());
|
|
||||||
}
|
|
||||||
|
|
||||||
[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]
|
|
||||||
[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_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_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));
|
|
||||||
}
|
|
||||||
|
|
||||||
[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 VoidTestMethod();
|
|
||||||
int TestMethodReturnsInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class TestAbstractClass
|
|
||||||
{
|
|
||||||
public int CalledTimes { get; set; }
|
|
||||||
|
|
||||||
public abstract void VoidAbstractMethod();
|
|
||||||
|
|
||||||
public abstract int AbstractMethodReturnsSameInt(int i);
|
|
||||||
|
|
||||||
public virtual int MethodReturnsSameInt(int i)
|
|
||||||
{
|
|
||||||
CalledTimes++;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TestClass : TestAbstractClass
|
|
||||||
{
|
|
||||||
|
|
||||||
public virtual int VirtualMethodReturnsSameInt(int i)
|
|
||||||
{
|
|
||||||
CalledTimes++;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual object VirtualMethodReturnsSameObject(object o)
|
|
||||||
{
|
|
||||||
CalledTimes++;
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void VoidVirtualMethod()
|
|
||||||
{
|
|
||||||
CalledTimes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void VoidAbstractMethod()
|
|
||||||
{
|
|
||||||
CalledTimes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int AbstractMethodReturnsSameInt(int i)
|
|
||||||
{
|
|
||||||
CalledTimes++;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -71,7 +71,7 @@
|
||||||
<Compile Include="ArgumentInvocationFromMatchers.cs" />
|
<Compile Include="ArgumentInvocationFromMatchers.cs" />
|
||||||
<Compile Include="ArgDoFromMatcher.cs" />
|
<Compile Include="ArgDoFromMatcher.cs" />
|
||||||
<Compile Include="AutoValuesForSubs.cs" />
|
<Compile Include="AutoValuesForSubs.cs" />
|
||||||
<Compile Include="CallBaseForMember.cs" />
|
<Compile Include="PartialSubs.cs" />
|
||||||
<Compile Include="FieldReports\CallingIntoNewSubWithinReturns.cs" />
|
<Compile Include="FieldReports\CallingIntoNewSubWithinReturns.cs" />
|
||||||
<Compile Include="FieldReports\Issue110_CustomExceptions.cs" />
|
<Compile Include="FieldReports\Issue110_CustomExceptions.cs" />
|
||||||
<Compile Include="FieldReports\Issue118_ConcreteClassWithPublicStaticMethod.cs" />
|
<Compile Include="FieldReports\Issue118_ConcreteClassWithPublicStaticMethod.cs" />
|
||||||
|
|
|
@ -36,8 +36,7 @@ namespace NSubstitute.Acceptance.Specs
|
||||||
[Test]
|
[Test]
|
||||||
public void ValidFormSubmission()
|
public void ValidFormSubmission()
|
||||||
{
|
{
|
||||||
var form = Substitute.For<Form>();
|
var form = Substitute.ForPartsOf<Form>();
|
||||||
form.Submit().Returns(x => x.CallBase());
|
|
||||||
form.Validate().Returns(new FormResult() { IsValid = true });
|
form.Validate().Returns(new FormResult() { IsValid = true });
|
||||||
|
|
||||||
var result = form.Submit();
|
var result = form.Submit();
|
||||||
|
@ -49,8 +48,7 @@ namespace NSubstitute.Acceptance.Specs
|
||||||
[Test]
|
[Test]
|
||||||
public void InvalidFormSubmission()
|
public void InvalidFormSubmission()
|
||||||
{
|
{
|
||||||
var form = Substitute.For<Form>();
|
var form = Substitute.ForPartsOf<Form>();
|
||||||
form.Submit().Returns(x => x.CallBase());
|
|
||||||
form.Validate().Returns(new FormResult() { IsValid = false });
|
form.Validate().Returns(new FormResult() { IsValid = false });
|
||||||
|
|
||||||
var result = form.Submit();
|
var result = form.Submit();
|
||||||
|
@ -74,18 +72,6 @@ namespace NSubstitute.Acceptance.Specs
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ShouldSumAllNumbersInFile()
|
public void ShouldSumAllNumbersInFile()
|
||||||
{
|
|
||||||
var reader = Substitute.For<SummingReader>();
|
|
||||||
reader.Read().Returns(x => x.CallBase());
|
|
||||||
reader.ReadFile().Returns("1,2,3,4,5");
|
|
||||||
|
|
||||||
var result = reader.Read();
|
|
||||||
|
|
||||||
Assert.That(result, Is.EqualTo(15));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ShouldSumAllNumberInFileWithPartialSub()
|
|
||||||
{
|
{
|
||||||
var reader = Substitute.ForPartsOf<SummingReader>();
|
var reader = Substitute.ForPartsOf<SummingReader>();
|
||||||
reader.ReadFile().Returns("1,2,3,4,5");
|
reader.ReadFile().Returns("1,2,3,4,5");
|
||||||
|
@ -122,23 +108,6 @@ namespace NSubstitute.Acceptance.Specs
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void AddTask()
|
public void AddTask()
|
||||||
{
|
|
||||||
var list = Substitute.For<TaskList>();
|
|
||||||
list.WhenForAnyArgs(x => x.Add("")).Do(x => x.CallBase());
|
|
||||||
list.ToArray().Returns(x => x.CallBase());
|
|
||||||
|
|
||||||
var view = new TaskView(list);
|
|
||||||
view.TaskEntryField = "write example";
|
|
||||||
|
|
||||||
view.ClickButton();
|
|
||||||
|
|
||||||
// list substitute functions as test spy
|
|
||||||
list.Received().Add("write example");
|
|
||||||
Assert.That(view.DisplayedTasks, Is.EqualTo(new[] { "write example" }));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void AddTaskUsingPartialSub()
|
|
||||||
{
|
{
|
||||||
var list = Substitute.ForPartsOf<TaskList>();
|
var list = Substitute.ForPartsOf<TaskList>();
|
||||||
var view = new TaskView(list);
|
var view = new TaskView(list);
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
using System;
|
||||||
|
using NSubstitute.Exceptions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace NSubstitute.Acceptance.Specs
|
||||||
|
{
|
||||||
|
public class PartialSubs
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void CanNotCreatePartialSubForInterface()
|
||||||
|
{
|
||||||
|
Assert.Throws<CanNotPartiallySubForInterfaceOrDelegateException>(() => Substitute.ForPartsOf<ITestInterface>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CanNotCreatePartialSubForDelegate()
|
||||||
|
{
|
||||||
|
Assert.Throws<CanNotPartiallySubForInterfaceOrDelegateException>(() => Substitute.ForPartsOf<Action>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CanNotCreatePartialSubForEventHander()
|
||||||
|
{
|
||||||
|
Assert.Throws<CanNotPartiallySubForInterfaceOrDelegateException>(() => Substitute.ForPartsOf<EventHandler>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CallAbstractMethod()
|
||||||
|
{
|
||||||
|
var testAbstractClass = Substitute.ForPartsOf<TestAbstractClass>();
|
||||||
|
testAbstractClass.VoidAbstractMethod();
|
||||||
|
var result = testAbstractClass.AbstractMethodReturnsSameInt(123);
|
||||||
|
Assert.AreEqual(0, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void SpyOnAbstractMethod()
|
||||||
|
{
|
||||||
|
var wasCalled = false;
|
||||||
|
var testAbstractClass = Substitute.ForPartsOf<TestAbstractClass>();
|
||||||
|
testAbstractClass.When(x => x.VoidAbstractMethod()).Do(x => wasCalled = true); ;
|
||||||
|
testAbstractClass.VoidAbstractMethod();
|
||||||
|
Assert.That(wasCalled);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ShouldCallBaseImplementationForVirtualMember()
|
||||||
|
{
|
||||||
|
var testClass = Substitute.ForPartsOf<TestClass>();
|
||||||
|
testClass.VoidVirtualMethod();
|
||||||
|
testClass.VoidVirtualMethod();
|
||||||
|
testClass.VoidVirtualMethod();
|
||||||
|
Assert.That(testClass.CalledTimes, Is.EqualTo(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void StopCallingBaseImplementationForVirtualMember()
|
||||||
|
{
|
||||||
|
var testClass = Substitute.ForPartsOf<TestClass>();
|
||||||
|
testClass.When(x => x.VoidVirtualMethod()).DoNotCallBase();
|
||||||
|
testClass.VoidVirtualMethod();
|
||||||
|
testClass.VoidVirtualMethod();
|
||||||
|
Assert.That(testClass.CalledTimes, Is.EqualTo(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void StopCallingBaseAndDoSomethingInstead()
|
||||||
|
{
|
||||||
|
var wasCalled = false;
|
||||||
|
var testClass = Substitute.ForPartsOf<TestClass>();
|
||||||
|
testClass.When(x => x.VoidAbstractMethod())
|
||||||
|
.DoNotCallBase()
|
||||||
|
.Do(x => wasCalled = true);
|
||||||
|
testClass.VoidAbstractMethod();
|
||||||
|
Assert.That(testClass.CalledTimes, Is.EqualTo(0));
|
||||||
|
Assert.That(wasCalled);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void UseImplementedVirtualMethod()
|
||||||
|
{
|
||||||
|
var testAbstractClass = Substitute.ForPartsOf<TestAbstractClass>();
|
||||||
|
Assert.That(testAbstractClass.MethodReturnsSameInt(1), Is.EqualTo(1));
|
||||||
|
Assert.That(testAbstractClass.CalledTimes, Is.EqualTo(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ReturnDefaultForUnimplementedAbstractMethod()
|
||||||
|
{
|
||||||
|
var testAbstractClass = Substitute.ForPartsOf<TestAbstractClass>();
|
||||||
|
Assert.AreEqual(default(int), testAbstractClass.AbstractMethodReturnsSameInt(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void OverrideBaseMethodsReturnValueStopsItFromCallingBase()
|
||||||
|
{
|
||||||
|
var testAbstractClass = Substitute.ForPartsOf<TestAbstractClass>();
|
||||||
|
testAbstractClass.MethodReturnsSameInt(Arg.Any<int>()).Returns(x => 42);
|
||||||
|
Assert.That(testAbstractClass.MethodReturnsSameInt(1), Is.EqualTo(42));
|
||||||
|
Assert.That(testAbstractClass.CalledTimes, Is.EqualTo(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void OverrideVirtualMethodReturnValueStopsItFromCallingBase()
|
||||||
|
{
|
||||||
|
var testClass = Substitute.ForPartsOf<TestClass>();
|
||||||
|
testClass.VirtualMethodReturnsSameInt(Arg.Any<int>()).Returns(2);
|
||||||
|
Assert.That(testClass.VirtualMethodReturnsSameInt(1), Is.EqualTo(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void OverrideWithMultipleReturns()
|
||||||
|
{
|
||||||
|
var testClass = Substitute.ForPartsOf<TestClass>();
|
||||||
|
testClass.VirtualMethodReturnsSameInt(Arg.Any<int>())
|
||||||
|
.Returns(x => 1, x => 2, x => 3);
|
||||||
|
Assert.That(testClass.VirtualMethodReturnsSameInt(10), Is.EqualTo(1));
|
||||||
|
Assert.That(testClass.VirtualMethodReturnsSameInt(10), Is.EqualTo(2));
|
||||||
|
Assert.That(testClass.VirtualMethodReturnsSameInt(10), Is.EqualTo(3));
|
||||||
|
Assert.That(testClass.VirtualMethodReturnsSameInt(10), Is.EqualTo(3));
|
||||||
|
Assert.That(testClass.CalledTimes, Is.EqualTo(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ITestInterface
|
||||||
|
{
|
||||||
|
void VoidTestMethod();
|
||||||
|
int TestMethodReturnsInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class TestAbstractClass
|
||||||
|
{
|
||||||
|
public int CalledTimes { get; set; }
|
||||||
|
|
||||||
|
public abstract void VoidAbstractMethod();
|
||||||
|
|
||||||
|
public abstract int AbstractMethodReturnsSameInt(int i);
|
||||||
|
|
||||||
|
public virtual int MethodReturnsSameInt(int i)
|
||||||
|
{
|
||||||
|
CalledTimes++;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestClass : TestAbstractClass
|
||||||
|
{
|
||||||
|
|
||||||
|
public virtual int VirtualMethodReturnsSameInt(int i)
|
||||||
|
{
|
||||||
|
CalledTimes++;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual object VirtualMethodReturnsSameObject(object o)
|
||||||
|
{
|
||||||
|
CalledTimes++;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void VoidVirtualMethod()
|
||||||
|
{
|
||||||
|
CalledTimes++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void VoidAbstractMethod()
|
||||||
|
{
|
||||||
|
CalledTimes++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int AbstractMethodReturnsSameInt(int i)
|
||||||
|
{
|
||||||
|
CalledTimes++;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ namespace NSubstitute.Specs
|
||||||
public override void Context()
|
public override void Context()
|
||||||
{
|
{
|
||||||
_call = mock<ICall>();
|
_call = mock<ICall>();
|
||||||
_callInfo = new CallInfo(new Argument[0], null);
|
_callInfo = new CallInfo(new Argument[0]);
|
||||||
_callInfoFactory = mock<ICallInfoFactory>();
|
_callInfoFactory = mock<ICallInfoFactory>();
|
||||||
_callInfoFactory.stub(x => x.Create(_call)).Return(_callInfo);
|
_callInfoFactory.stub(x => x.Create(_call)).Return(_callInfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ namespace NSubstitute.Specs
|
||||||
|
|
||||||
public override CallInfo CreateSubjectUnderTest()
|
public override CallInfo CreateSubjectUnderTest()
|
||||||
{
|
{
|
||||||
return new CallInfo(_arguments, null);
|
return new CallInfo(_arguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ namespace NSubstitute.Specs
|
||||||
[Test]
|
[Test]
|
||||||
public void Match_argument_by_declared_type_when_an_exact_match_is_found()
|
public void Match_argument_by_declared_type_when_an_exact_match_is_found()
|
||||||
{
|
{
|
||||||
var sut = new CallInfo(new[] { CreateArg<object>("hello"), CreateArg("world") }, null);
|
var sut = new CallInfo(new[] { CreateArg<object>("hello"), CreateArg("world") });
|
||||||
|
|
||||||
Assert.That(sut.Arg<object>(), Is.EqualTo("hello"));
|
Assert.That(sut.Arg<object>(), Is.EqualTo("hello"));
|
||||||
Assert.That(sut.Arg<string>(), Is.EqualTo("world"));
|
Assert.That(sut.Arg<string>(), Is.EqualTo("world"));
|
||||||
|
@ -81,7 +81,7 @@ namespace NSubstitute.Specs
|
||||||
[Test]
|
[Test]
|
||||||
public void Match_argument_by_actual_type_when_no_declared_type_match_is_found()
|
public void Match_argument_by_actual_type_when_no_declared_type_match_is_found()
|
||||||
{
|
{
|
||||||
var sut = new CallInfo(new[] { CreateArg<object>(123), CreateArg<object>("hello") }, null);
|
var sut = new CallInfo(new[] { CreateArg<object>(123), CreateArg<object>("hello") });
|
||||||
|
|
||||||
Assert.That(sut.Arg<string>(), Is.EqualTo("hello"));
|
Assert.That(sut.Arg<string>(), Is.EqualTo("hello"));
|
||||||
Assert.That(sut.Arg<int>(), Is.EqualTo(123));
|
Assert.That(sut.Arg<int>(), Is.EqualTo(123));
|
||||||
|
@ -91,7 +91,7 @@ namespace NSubstitute.Specs
|
||||||
public void Match_argument_by_actual_type_when_no_declared_type_match_is_found_and_when_a_compatible_argument_is_provided()
|
public void Match_argument_by_actual_type_when_no_declared_type_match_is_found_and_when_a_compatible_argument_is_provided()
|
||||||
{
|
{
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
var sut = new CallInfo(new[] { CreateArg<object>("asdf"), CreateArg<object>(list) }, null);
|
var sut = new CallInfo(new[] { CreateArg<object>("asdf"), CreateArg<object>(list) });
|
||||||
Assert.That(sut.Arg<IEnumerable<int>>(), Is.SameAs(list));
|
Assert.That(sut.Arg<IEnumerable<int>>(), Is.SameAs(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ namespace NSubstitute.Specs
|
||||||
public void Match_by_ref_type_arguments_when_argument_that_is_the_non_by_ref_type_is_provided()
|
public void Match_by_ref_type_arguments_when_argument_that_is_the_non_by_ref_type_is_provided()
|
||||||
{
|
{
|
||||||
const int expectedResult = 5;
|
const int expectedResult = 5;
|
||||||
var sut = new CallInfo(new[] { CreateArg<object>("aasdf"), new ByRefArgument<int>(expectedResult) }, null);
|
var sut = new CallInfo(new[] { CreateArg<object>("aasdf"), new ByRefArgument<int>(expectedResult) });
|
||||||
Assert.That(sut.Arg<int>(), Is.EqualTo(expectedResult));
|
Assert.That(sut.Arg<int>(), Is.EqualTo(expectedResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,14 +107,14 @@ namespace NSubstitute.Specs
|
||||||
public void Match_by_ref_type_arguments_when_argument_compatbile_non_by_ref_type_is_provided()
|
public void Match_by_ref_type_arguments_when_argument_compatbile_non_by_ref_type_is_provided()
|
||||||
{
|
{
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
var sut = new CallInfo(new[] { CreateArg<object>("aasdf"), new ByRefArgument<List<int>>(list) }, null);
|
var sut = new CallInfo(new[] { CreateArg<object>("aasdf"), new ByRefArgument<List<int>>(list) });
|
||||||
Assert.That(sut.Arg<IEnumerable<int>>(), Is.EqualTo(list));
|
Assert.That(sut.Arg<IEnumerable<int>>(), Is.EqualTo(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Throw_when_there_is_no_declared_type_match_but_multiple_compatible_arguments()
|
public void Throw_when_there_is_no_declared_type_match_but_multiple_compatible_arguments()
|
||||||
{
|
{
|
||||||
var sut = new CallInfo(new[] { CreateArg<object>("a"), CreateArg<object>("b") }, null);
|
var sut = new CallInfo(new[] { CreateArg<object>("a"), CreateArg<object>("b") });
|
||||||
Assert.Throws<AmbiguousArgumentsException>(() => sut.Arg<string>());
|
Assert.Throws<AmbiguousArgumentsException>(() => sut.Arg<string>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ namespace NSubstitute.Specs
|
||||||
[Test]
|
[Test]
|
||||||
public void Throw_when_setting_argument_that_is_not_passed_by_ref()
|
public void Throw_when_setting_argument_that_is_not_passed_by_ref()
|
||||||
{
|
{
|
||||||
var sut = new CallInfo(new[] { CreateArg(1) }, null);
|
var sut = new CallInfo(new[] { CreateArg(1) });
|
||||||
|
|
||||||
Assert.Throws<ArgumentIsNotOutOrRefException>(() => sut[0] = 123);
|
Assert.Throws<ArgumentIsNotOutOrRefException>(() => sut[0] = 123);
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ namespace NSubstitute.Specs
|
||||||
[Test]
|
[Test]
|
||||||
public void Throw_when_setting_by_ref_argument_with_an_incompatible_value()
|
public void Throw_when_setting_by_ref_argument_with_an_incompatible_value()
|
||||||
{
|
{
|
||||||
var sut = new CallInfo(new[] { new ByRefArgument<object>("needs a string") }, null);
|
var sut = new CallInfo(new[] { new ByRefArgument<object>("needs a string") });
|
||||||
|
|
||||||
Assert.Throws<ArgumentSetWithIncompatibleValueException>(() => sut[0] = new object());
|
Assert.Throws<ArgumentSetWithIncompatibleValueException>(() => sut[0] = new object());
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace NSubstitute.Specs
|
||||||
|
|
||||||
protected CallInfo StubCallInfoForCall(ICall call)
|
protected CallInfo StubCallInfoForCall(ICall call)
|
||||||
{
|
{
|
||||||
var callInfo = new CallInfo(new Argument[0], null);
|
var callInfo = new CallInfo(new Argument[0]);
|
||||||
_callInfoFactory.stub(x => x.Create(call)).Return(callInfo);
|
_callInfoFactory.stub(x => x.Create(call)).Return(callInfo);
|
||||||
return callInfo;
|
return callInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace NSubstitute.Specs
|
||||||
|
|
||||||
public override void Context()
|
public override void Context()
|
||||||
{
|
{
|
||||||
_callInfo = new CallInfo(new Argument[0], null);
|
_callInfo = new CallInfo(new Argument[0]);
|
||||||
_func = mock<Func<CallInfo, string>>();
|
_func = mock<Func<CallInfo, string>>();
|
||||||
_func.stub(x => x(_callInfo)).Return(ValueToReturn);
|
_func.stub(x => x(_callInfo)).Return(ValueToReturn);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ namespace NSubstitute.Specs
|
||||||
[Test]
|
[Test]
|
||||||
public void Should_return_null()
|
public void Should_return_null()
|
||||||
{
|
{
|
||||||
Assert.That(sut.ReturnFor(new CallInfo(new Argument[0], null)), Is.Null);
|
Assert.That(sut.ReturnFor(new CallInfo(new Argument[0])), Is.Null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ReturnValueFromFunc<string> CreateSubjectUnderTest()
|
public override ReturnValueFromFunc<string> CreateSubjectUnderTest()
|
||||||
|
|
|
@ -8,12 +8,10 @@ namespace NSubstitute.Core
|
||||||
public class CallInfo
|
public class CallInfo
|
||||||
{
|
{
|
||||||
private readonly Argument[] _callArguments;
|
private readonly Argument[] _callArguments;
|
||||||
private readonly Func<object> _callBase;
|
|
||||||
|
|
||||||
public CallInfo(Argument[] callArguments, Func<object> callBase)
|
public CallInfo(Argument[] callArguments)
|
||||||
{
|
{
|
||||||
_callArguments = callArguments;
|
_callArguments = callArguments;
|
||||||
_callBase = callBase;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -77,15 +75,6 @@ namespace NSubstitute.Core
|
||||||
throw new ArgumentNotFoundException("Can not find an argument of type " + typeof(T).FullName + " to this call.");
|
throw new ArgumentNotFoundException("Can not find an argument of type " + typeof(T).FullName + " to this call.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Call the underlying base implementation of this call, if this is for a virtual member.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public object CallBase()
|
|
||||||
{
|
|
||||||
return _callBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool TryGetArg<T>(Func<Argument, bool> condition, out T value)
|
private bool TryGetArg<T>(Func<Argument, bool> condition, out T value)
|
||||||
{
|
{
|
||||||
value = default(T);
|
value = default(T);
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace NSubstitute.Core
|
||||||
public CallInfo Create(ICall call)
|
public CallInfo Create(ICall call)
|
||||||
{
|
{
|
||||||
var arguments = GetArgumentsFromCall(call).ToArray();
|
var arguments = GetArgumentsFromCall(call).ToArray();
|
||||||
return new CallInfo(arguments, call.CallBase);
|
return new CallInfo(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<Argument> GetArgumentsFromCall(ICall call)
|
private static IEnumerable<Argument> GetArgumentsFromCall(ICall call)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using NSubstitute.Exceptions;
|
||||||
|
|
||||||
namespace NSubstitute.Core
|
namespace NSubstitute.Core
|
||||||
{
|
{
|
||||||
|
@ -39,6 +40,11 @@ namespace NSubstitute.Core
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public object CreatePartial(Type[] typesToProxy, object[] constructorArguments)
|
public object CreatePartial(Type[] typesToProxy, object[] constructorArguments)
|
||||||
{
|
{
|
||||||
|
var primaryProxyType = GetPrimaryProxyType(typesToProxy);
|
||||||
|
if (primaryProxyType.IsSubclassOf(typeof (Delegate)) || !primaryProxyType.IsClass)
|
||||||
|
{
|
||||||
|
throw new CanNotPartiallySubForInterfaceOrDelegateException(primaryProxyType);
|
||||||
|
}
|
||||||
return Create(typesToProxy, constructorArguments, true);
|
return Create(typesToProxy, constructorArguments, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,5 +29,11 @@ namespace NSubstitute.Core
|
||||||
_callRouter.SetRoute(x => _routeFactory.DoWhenCalled(x, callbackWithArguments, _matchArgs));
|
_callRouter.SetRoute(x => _routeFactory.DoWhenCalled(x, callbackWithArguments, _matchArgs));
|
||||||
_call(_substitute);
|
_call(_substitute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WhenCalled<T> DoNotCallBase()
|
||||||
|
{
|
||||||
|
//TODO: stop this call from going through to base
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
using System;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
|
||||||
|
namespace NSubstitute.Exceptions
|
||||||
|
{
|
||||||
|
public class CanNotPartiallySubForInterfaceOrDelegateException : SubstituteException
|
||||||
|
{
|
||||||
|
public CanNotPartiallySubForInterfaceOrDelegateException(Type type) : base(DescribeProblem(type)) { }
|
||||||
|
protected CanNotPartiallySubForInterfaceOrDelegateException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
||||||
|
|
||||||
|
private static string DescribeProblem(Type type)
|
||||||
|
{
|
||||||
|
return string.Format("Can only substitute for parts of classes, not interfaces or delegates. "
|
||||||
|
+ "Try `Substitute.For<{0}> instead.", type.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -149,9 +149,10 @@
|
||||||
<Compile Include="Exceptions\ArgumentIsNotOutOrRefException.cs" />
|
<Compile Include="Exceptions\ArgumentIsNotOutOrRefException.cs" />
|
||||||
<Compile Include="Exceptions\ArgumentSetWithIncompatibleValueException.cs" />
|
<Compile Include="Exceptions\ArgumentSetWithIncompatibleValueException.cs" />
|
||||||
<Compile Include="Exceptions\CallSequenceNotFoundException.cs" />
|
<Compile Include="Exceptions\CallSequenceNotFoundException.cs" />
|
||||||
<Compile Include="Exceptions\CouldNotCallBaseException.cs" />
|
<Compile Include="Exceptions\CanNotPartiallySubForInterfaceOrDelegateException.cs" />
|
||||||
<Compile Include="Exceptions\CannotCreateEventArgsException.cs" />
|
<Compile Include="Exceptions\CannotCreateEventArgsException.cs" />
|
||||||
<Compile Include="Exceptions\CannotReturnNullForValueType.cs" />
|
<Compile Include="Exceptions\CannotReturnNullForValueType.cs" />
|
||||||
|
<Compile Include="Exceptions\CouldNotCallBaseException.cs" />
|
||||||
<Compile Include="Exceptions\CouldNotSetReturnException.cs" />
|
<Compile Include="Exceptions\CouldNotSetReturnException.cs" />
|
||||||
<Compile Include="Exceptions\MissingSequenceNumberException.cs" />
|
<Compile Include="Exceptions\MissingSequenceNumberException.cs" />
|
||||||
<Compile Include="Exceptions\NotRunningAQueryException.cs" />
|
<Compile Include="Exceptions\NotRunningAQueryException.cs" />
|
||||||
|
|
Загрузка…
Ссылка в новой задаче