From 24f33d87502f1ec83be4165ad17191894ea7fc6c Mon Sep 17 00:00:00 2001 From: Huy Hoang <10050270+hhoangnl@users.noreply.github.com> Date: Tue, 13 Oct 2020 17:56:56 +0200 Subject: [PATCH] Add WithDependency(T2, Action) overload to support calling T2-specific methods. --- .../FluentArrange.NSubstitute.csproj | 7 +- .../FluentArrangeContextTests.cs | 88 ++++++++++++++----- FluentArrange/FluentArrange.csproj | 8 +- FluentArrange/FluentArrangeContext.cs | 21 ++++- README.MD | 9 ++ 5 files changed, 98 insertions(+), 35 deletions(-) diff --git a/FluentArrange.NSubstitute/FluentArrange.NSubstitute.csproj b/FluentArrange.NSubstitute/FluentArrange.NSubstitute.csproj index a1dbbaa..409a495 100644 --- a/FluentArrange.NSubstitute/FluentArrange.NSubstitute.csproj +++ b/FluentArrange.NSubstitute/FluentArrange.NSubstitute.csproj @@ -3,13 +3,12 @@ netstandard2.0 8.0 - 0.2.0-alpha + 0.3.0-alpha FluentArrange using NSubstitute as mocking framework. https://github.com/hhoangnl/FluentArrange https://github.com/hhoangnl/FluentArrange - Added overloads to accept instances: -- WithDependency<T>(T) -- WithDependency<T>(T, Action<T>) + Added overload to configure and call T2-specific methods: +- WithDependency<T, T2>(T2, Action<T2>) AAA TDD mocking unit-testing nsubstitute Huy Hoang Huy Hoang diff --git a/FluentArrange.Tests/FluentArrangeContextTests.cs b/FluentArrange.Tests/FluentArrangeContextTests.cs index 739d1ad..3059dd9 100644 --- a/FluentArrange.Tests/FluentArrangeContextTests.cs +++ b/FluentArrange.Tests/FluentArrangeContextTests.cs @@ -12,24 +12,24 @@ namespace FluentArrange.Tests public class FluentArrangeContextTests { [Fact] - public void WithDependency_DependencyTypeNotFound_ShouldNotCallConfigureDependency() + public void WithDependency_TypeNotFound_ShouldNotInvokeAction() { // Arrange - var called = false; + var invoked = false; var sut = new FluentArrangeContext(new Dictionary()); // Act - sut.WithDependency(e => called = true); + sut.WithDependency(e => invoked = true); // Assert - called.Should().BeFalse(); + invoked.Should().BeFalse(); } [Fact] - public void WithDependency_DependencyTypeFound_ShouldInvokeConfigureDependency() + public void WithDependency_TypeFound_ShouldInvokeAction() { // Arrange - var called = false; + var invoked = false; var dependencies = new Dictionary { {typeof(IAccountRepository), new AccountRepository()} @@ -37,14 +37,14 @@ public void WithDependency_DependencyTypeFound_ShouldInvokeConfigureDependency() var sut = new FluentArrangeContext(dependencies); // Act - sut.WithDependency(e => called = true); + sut.WithDependency(e => invoked = true); // Assert - called.Should().BeTrue(); + invoked.Should().BeTrue(); } [Fact] - public void WithDependency_ShouldReturnReferenceToSut() + public void WithDependency_Type_ShouldReturnReferenceToSut() { // Arrange var sut = new FluentArrangeContext(new Dictionary()); @@ -57,27 +57,27 @@ public void WithDependency_ShouldReturnReferenceToSut() } [Fact] - public void BuildSut_DependencyContainsInstance_BuiltSutShouldContainDependencyInstance() + public void WithDependency_T_InstanceTypeFound_DependenciesShouldContainInstance() { // Arrange - var dependency = new AccountRepository(); var dependencies = new Dictionary { - {typeof(IAccountRepository), dependency} + {typeof(IAccountRepository), new AccountRepository()} }; - var sut = new FluentArrangeContext(dependencies) - .WithDependency(e => { }); + var sut = new FluentArrangeContext(dependencies); + + var newInstance = new AccountRepository(); // Act - var result = sut.BuildSut(); + sut.WithDependency(newInstance); // Assert - result.AccountRepository.Should().Be(dependency); + sut.Dependencies[typeof(IAccountRepository)].Should().Be(newInstance); } [Fact] - public void WithDependency_Instance_DependenciesShouldContainInstance() + public void WithDependency_T_InstanceTypeNotFound_ShouldThrowInvalidOperationException() { // Arrange var dependencies = new Dictionary @@ -87,17 +87,36 @@ public void WithDependency_Instance_DependenciesShouldContainInstance() var sut = new FluentArrangeContext(dependencies); - var newInstance = new AccountRepository(); + // Act + Action act = () => sut.WithDependency(new Foo()); + + // Assert + act.Should().Throw() + .And.Message.Should().Be("No dependency found of type FluentArrange.Tests.TestClasses.IFoo"); + } + + [Fact] + public void WithDependency_T2_T3_InstanceTypeFound_ShouldInvokeAction() + { + // Arrange + var dependencies = new Dictionary + { + {typeof(IAccountRepository), new AccountRepository()} + }; + + var sut = new FluentArrangeContext(dependencies); + + var invoked = false; // Act - sut.WithDependency(newInstance); + sut.WithDependency(new AccountRepository(), repository => invoked = true); // Assert - sut.Dependencies[typeof(IAccountRepository)].Should().Be(newInstance); + invoked.Should().BeTrue(); } [Fact] - public void WithDependency_Instance_TypeNotFound_ShouldThrowInvalidOperationException() + public void WithDependency_T2_T3_InstanceTypeFound_DependenciesShouldContainInstance() { // Arrange var dependencies = new Dictionary @@ -107,12 +126,33 @@ public void WithDependency_Instance_TypeNotFound_ShouldThrowInvalidOperationExce var sut = new FluentArrangeContext(dependencies); + var instance = new AccountRepository(); + // Act - Action act = () => sut.WithDependency(new Foo()); + sut.WithDependency(instance, repository => { }); // Assert - act.Should().Throw() - .And.Message.Should().Be("No dependency found of type FluentArrange.Tests.TestClasses.IFoo"); + sut.Dependencies[typeof(IAccountRepository)].Should().Be(instance); + } + + [Fact] + public void BuildSut_DependencyContainsInstance_BuiltSutShouldContainDependencyInstance() + { + // Arrange + var dependency = new AccountRepository(); + var dependencies = new Dictionary + { + {typeof(IAccountRepository), dependency} + }; + + var sut = new FluentArrangeContext(dependencies) + .WithDependency(e => { }); + + // Act + var result = sut.BuildSut(); + + // Assert + result.AccountRepository.Should().Be(dependency); } } } \ No newline at end of file diff --git a/FluentArrange/FluentArrange.csproj b/FluentArrange/FluentArrange.csproj index c05d0f5..764e31a 100644 --- a/FluentArrange/FluentArrange.csproj +++ b/FluentArrange/FluentArrange.csproj @@ -3,13 +3,13 @@ netstandard2.0 8.0 - 0.2.0-alpha + 0.3.0-alpha Write clean Arrange code using Fluent syntax. https://github.com/hhoangnl/FluentArrange https://github.com/hhoangnl/FluentArrange - Added overloads to accept instances: -- WithDependency<T>(T) -- WithDependency<T>(T, Action<T>) + Added overload to configure and call T2-specific methods: +- WithDependency<T, T2>(T2, Action<T2>) + AAA TDD mocking unit-testing Huy Hoang Huy Hoang diff --git a/FluentArrange/FluentArrangeContext.cs b/FluentArrange/FluentArrangeContext.cs index 77e062c..49ca85e 100644 --- a/FluentArrange/FluentArrangeContext.cs +++ b/FluentArrange/FluentArrangeContext.cs @@ -21,7 +21,8 @@ internal FluentArrangeContext(Dictionary dependencies) public T Sut => _sut ??= BuildSut(); - public FluentArrangeContext WithDependency(Action configureDependency) where T2 : class + public FluentArrangeContext WithDependency(Action configureDependency) + where T2 : class { if (Dependencies.TryGetValue(typeof(T2), out var value) && value is T2 dependency) { @@ -31,7 +32,8 @@ public FluentArrangeContext WithDependency(Action configureDependency return this; } - public FluentArrangeContext WithDependency(T2 instance) where T2 : class + public FluentArrangeContext WithDependency(T2 instance) + where T2 : class { _ = Dependency(); @@ -40,7 +42,20 @@ public FluentArrangeContext WithDependency(T2 instance) where T2 : class return this; } - public FluentArrangeContext WithDependency(T2 instance, Action configureInstance) where T2 : class + public FluentArrangeContext WithDependency(T2 instance, Action configureInstance) + where T2 : class + { + _ = Dependency(); + + Dependencies[typeof(T2)] = instance; + configureInstance(instance); + + return this; + } + + public FluentArrangeContext WithDependency(T3 instance, Action configureInstance) + where T2 : class + where T3 : T2 { _ = Dependency(); diff --git a/README.MD b/README.MD index 73f5d2c..47a49ec 100644 --- a/README.MD +++ b/README.MD @@ -68,6 +68,15 @@ var context = Arrange.Sut() }); ~~~ +or `WithDependency(T2, Action)` if you need to call `T2`-specific methods: +~~~ C# +var context = Arrange.Sut() + .WithDependency(new InMemoryAccountService(), d => + { + d.AddTestAccounts(); + }); +~~~ + ## Asserting Dependencies Suppose you need to assert that a dependency's method has been called. Well, you simply arrange code with `Arrange.For` instead of `Arrange.Sut` to get a `FluentArrangeContext` object: