diff --git a/src/Samples/Specify.Samples/Domain/Atm/Card.cs b/src/Samples/Specify.Samples/Domain/Atm/Card.cs index e54ac89..dc194c5 100644 --- a/src/Samples/Specify.Samples/Domain/Atm/Card.cs +++ b/src/Samples/Specify.Samples/Domain/Atm/Card.cs @@ -1,19 +1,21 @@ namespace Specify.Samples.Domain.Atm { - public class Card - { - public int AccountBalance { get; set; } - private readonly bool _enabled; + public class Card + { + public virtual int AccountBalance { get; set; } + private readonly bool _enabled; - public Card(bool enabled, int accountBalance) - { - AccountBalance = accountBalance; - _enabled = enabled; - } + public Card(bool enabled, int accountBalance) + { + AccountBalance = accountBalance; + _enabled = enabled; + } - public bool Enabled - { - get { return _enabled; } - } - } + protected Card() { } + + public virtual bool Enabled + { + get { return _enabled; } + } + } } \ No newline at end of file diff --git a/src/Samples/Specify.Samples/Specs/ATM/CardHasBeenDisabled.cs b/src/Samples/Specify.Samples/Specs/ATM/CardHasBeenDisabled.cs index ed3c2d7..e39c855 100644 --- a/src/Samples/Specify.Samples/Specs/ATM/CardHasBeenDisabled.cs +++ b/src/Samples/Specify.Samples/Specs/ATM/CardHasBeenDisabled.cs @@ -1,4 +1,5 @@ -using Shouldly; +using NSubstitute; +using Shouldly; using Specify.Samples.Domain.Atm; using TestStack.BDDfy; @@ -6,18 +7,17 @@ namespace Specify.Samples.Specs.ATM { public class CardHasBeenDisabled : ScenarioFor { - private Card _card; - public void Given_the_Card_is_disabled() { - _card = new Card(false, 100); + The().Enabled.Returns(false); + The().AccountBalance.Returns(100); SUT = new Atm(100); } [When("When the account holder requests $20")] public void When_the_Account_Holder_requests_20_dollars() { - SUT.RequestMoney(_card, 20); + SUT.RequestMoney(The(), 20); } public void Then_the_Card_should_be_retained() diff --git a/src/app/Specify/TinyMockingContainer.cs b/src/app/Specify/TinyMockingContainer.cs index 78e92e4..e97a157 100644 --- a/src/app/Specify/TinyMockingContainer.cs +++ b/src/app/Specify/TinyMockingContainer.cs @@ -58,9 +58,19 @@ private void RegisterMocksIfNecessary(Type serviceType) if (constructor == null) { + // TinyIocContainer will construct class. return; } + if (constructor.HasAnyValueTypeParameters()) + { + // Mocking framework will construct class + RegisterMock(serviceType); + return; + } + + // serviceType is class with constructor only containing reference types. + // TinyIocContainer will construct class and register mocks with container for parameters that mocking framework will construct foreach (var parameterInfo in constructor.GetParameters()) { if (!Container.CanResolve(parameterInfo.ParameterType, ResolveOptions.FailUnregisteredAndNameNotFound)) diff --git a/src/app/Specify/TypeExtensions.cs b/src/app/Specify/TypeExtensions.cs index f08d9aa..9819eca 100644 --- a/src/app/Specify/TypeExtensions.cs +++ b/src/app/Specify/TypeExtensions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using TestStack.BDDfy; namespace Specify { @@ -105,6 +106,16 @@ internal static bool IsSimple(this Type type) typeof (List<>) }; + /// + /// Returns true if constructor has any value type parameters. + /// + /// The type. + /// True if constructor has any value type parameters, False if not + internal static bool HasAnyValueTypeParameters(this ConstructorInfo constructor) + { + return constructor.GetParameters().Any(parameter => parameter.ParameterType.IsValueType()); + } + internal static bool CanBeResolvedUsingContainer(this Type type, Func containerCanResolve, bool requiresRegistration = true) { if (type.IsClass()) diff --git a/src/tests/Specify.Tests/Stubs/AutoMockingStubs.cs b/src/tests/Specify.Tests/Stubs/AutoMockingStubs.cs index 19ff066..ea76348 100644 --- a/src/tests/Specify.Tests/Stubs/AutoMockingStubs.cs +++ b/src/tests/Specify.Tests/Stubs/AutoMockingStubs.cs @@ -50,6 +50,12 @@ public ConcreteObjectWithOneSealedConstructorHavingOneInterfaceConstructor(Seale SealedDependencyWithOneInterfaceConstructor = sealedDependencyWithOneInterfaceConstructor; } } + class ConcreteObjectWithValueTypeConstuctorParmeter + { + public ConcreteObjectWithValueTypeConstuctorParmeter(bool enabled, int accountBalance) + { + } + } class ConcreteObjectWithPrivateConstructor { private ConcreteObjectWithPrivateConstructor() diff --git a/src/tests/Specify.Tests/TypeExtensionTests.cs b/src/tests/Specify.Tests/TypeExtensionTests.cs index aeaf329..01f086a 100644 --- a/src/tests/Specify.Tests/TypeExtensionTests.cs +++ b/src/tests/Specify.Tests/TypeExtensionTests.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -89,6 +90,15 @@ public void IsEnumerable_should_return_true_if_type_is_enumerable() enumerable.GetType().IsEnumerable().ShouldBe(true); } + [TestCase(typeof(ConcreteObjectWithValueTypeConstuctorParmeter), true)] + [TestCase(typeof(ConcreteObjectWithOneInterfaceConstructor), false)] + [TestCase(typeof(ConcreteObjectWithOneConcreteConstructor), false)] + public void HasAnyValueTypeParameters_should_return_true_if_any_constructor_parameters_are_value_types(Type type, bool result) + { + type.GreediestConstructor().HasAnyValueTypeParameters().ShouldBe(result); + } + + //[Test] //public void GetTypeFromEnumerable_should_return_inner_type() //{