Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions src/Samples/Specify.Samples/Domain/Atm/Card.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
}
}
10 changes: 5 additions & 5 deletions src/Samples/Specify.Samples/Specs/ATM/CardHasBeenDisabled.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
using Shouldly;
using NSubstitute;
using Shouldly;
using Specify.Samples.Domain.Atm;
using TestStack.BDDfy;

namespace Specify.Samples.Specs.ATM
{
public class CardHasBeenDisabled : ScenarioFor<Atm, AccountHolderWithdrawsCashStory>
{
private Card _card;

public void Given_the_Card_is_disabled()
{
_card = new Card(false, 100);
The<Card>().Enabled.Returns(false);
The<Card>().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<Card>(), 20);
}

public void Then_the_Card_should_be_retained()
Expand Down
10 changes: 10 additions & 0 deletions src/app/Specify/TinyMockingContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
11 changes: 11 additions & 0 deletions src/app/Specify/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using TestStack.BDDfy;

namespace Specify
{
Expand Down Expand Up @@ -105,6 +106,16 @@ internal static bool IsSimple(this Type type)
typeof (List<>)
};

/// <summary>
/// Returns true if constructor has any value type parameters.
/// </summary>
/// <param name="constructor">The type.</param>
/// <returns>True if constructor has any value type parameters, False if not</returns>
internal static bool HasAnyValueTypeParameters(this ConstructorInfo constructor)
{
return constructor.GetParameters().Any(parameter => parameter.ParameterType.IsValueType());
}

internal static bool CanBeResolvedUsingContainer(this Type type, Func<Type, bool> containerCanResolve, bool requiresRegistration = true)
{
if (type.IsClass())
Expand Down
6 changes: 6 additions & 0 deletions src/tests/Specify.Tests/Stubs/AutoMockingStubs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ public ConcreteObjectWithOneSealedConstructorHavingOneInterfaceConstructor(Seale
SealedDependencyWithOneInterfaceConstructor = sealedDependencyWithOneInterfaceConstructor;
}
}
class ConcreteObjectWithValueTypeConstuctorParmeter
{
public ConcreteObjectWithValueTypeConstuctorParmeter(bool enabled, int accountBalance)
{
}
}
class ConcreteObjectWithPrivateConstructor
{
private ConcreteObjectWithPrivateConstructor()
Expand Down
10 changes: 10 additions & 0 deletions src/tests/Specify.Tests/TypeExtensionTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
Expand Down Expand Up @@ -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()
//{
Expand Down