In progress, removing CallBase()

This commit is contained in:
David Tchepak 2013-12-03 12:57:30 +11:00
Родитель 33679acfdd
Коммит d426c93754
14 изменённых файлов: 226 добавлений и 324 удалений

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

@ -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" />