Skip to content

Commit ab8b645

Browse files
committed
Added support for building NSubstitute proxies
1 parent f81a80e commit ab8b645

File tree

7 files changed

+92
-4
lines changed

7 files changed

+92
-4
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using NSubstitute;
3+
using NTestDataBuilder.Tests.Builders;
4+
using NUnit.Framework;
5+
6+
namespace NTestDataBuilder.Tests
7+
{
8+
class AsProxyTests
9+
{
10+
[Test]
11+
public void GivenBuilderIsSetAsProxy_WhenBuilding_AnNSubstituteProxyIsReturned()
12+
{
13+
var builder = new CustomerBuilder().AsProxy();
14+
15+
var proxy = builder.Build();
16+
17+
proxy.CustomerForHowManyYears(Arg.Any<DateTime>()).Returns(100);
18+
Assert.That(proxy.CustomerForHowManyYears(DateTime.Now), Is.EqualTo(100));
19+
}
20+
21+
[Test]
22+
public void GivenBuilderThatAltersProxyIsSetAsProxy_WhenBuilding_TheProxyIsAltered()
23+
{
24+
var builder = new ProxyAlteringCustomerBuilder().AsProxy();
25+
26+
var proxy = builder.Build();
27+
28+
Assert.That(proxy.CustomerForHowManyYears(DateTime.Now), Is.EqualTo(ProxyAlteringCustomerBuilder.MemberFor));
29+
}
30+
}
31+
}

NTestDataBuilder.Tests/Builders/BasicCustomerBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace NTestDataBuilder.Tests.Builders
44
{
55
class BasicCustomerBuilder : DataBuilder<Customer, BasicCustomerBuilder>
66
{
7-
public override Customer Build()
7+
protected override Customer BuildObject()
88
{
99
return new Customer("First Name", "Last Name", 2013);
1010
}

NTestDataBuilder.Tests/Builders/CustomerBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public CustomerBuilder WhoJoinedIn(int yearJoined)
4444
return this;
4545
}
4646

47-
public override Customer Build()
47+
protected override Customer BuildObject()
4848
{
4949
return new Customer(
5050
Get(x => x.FirstName),
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using NSubstitute;
3+
using NTestDataBuilder.Tests.Entities;
4+
5+
namespace NTestDataBuilder.Tests.Builders
6+
{
7+
class ProxyAlteringCustomerBuilder : DataBuilder<Customer, ProxyAlteringCustomerBuilder>
8+
{
9+
public const int MemberFor = 4;
10+
11+
protected override void AlterProxy(Customer proxy)
12+
{
13+
proxy.CustomerForHowManyYears(Arg.Any<DateTime>()).Returns(MemberFor);
14+
}
15+
16+
protected override Customer BuildObject()
17+
{
18+
throw new NotImplementedException();
19+
}
20+
}
21+
}

NTestDataBuilder.Tests/Entities/Customer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public Customer(string firstName, string lastName, int yearJoined)
1818
YearJoined = yearJoined;
1919
}
2020

21-
public int CustomerForHowManyYears(DateTime since)
21+
public virtual int CustomerForHowManyYears(DateTime since)
2222
{
2323
if (since.Year < YearJoined)
2424
throw new ArgumentException("Date must be on year or after year that customer joined.", "since");

NTestDataBuilder.Tests/NTestDataBuilder.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@
4747
<Reference Include="Microsoft.CSharp" />
4848
</ItemGroup>
4949
<ItemGroup>
50+
<Compile Include="AsProxyTests.cs" />
5051
<Compile Include="BuildDataListTests.cs" />
5152
<Compile Include="Builders\BasicCustomerBuilder.cs" />
5253
<Compile Include="Builders\CustomerBuilder.cs" />
54+
<Compile Include="Builders\ProxyAlteringCustomerBuilder.cs" />
5355
<Compile Include="BuildTests.cs" />
5456
<Compile Include="CreateListTests.cs" />
5557
<Compile Include="Entities\Customer.cs" />

NTestDataBuilder/DataBuilder.cs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,47 @@ public abstract class DataBuilder<TEntity, TBuilder> : IDataBuilder<TEntity>
2828
where TBuilder : class, IDataBuilder<TEntity>
2929
{
3030
private readonly Dictionary<string, object> _properties = new Dictionary<string, object>();
31+
private ProxyBuilder<TEntity> _proxyBuilder;
3132

3233
/// <summary>
3334
/// Build the object.
3435
/// </summary>
3536
/// <returns>The built object</returns>
36-
public abstract TEntity Build();
37+
public TEntity Build()
38+
{
39+
if (_proxyBuilder != null)
40+
{
41+
var proxy = _proxyBuilder.Build();
42+
AlterProxy(proxy);
43+
return proxy;
44+
}
45+
46+
return BuildObject();
47+
}
48+
49+
/// <summary>
50+
/// Build the actual object
51+
/// </summary>
52+
/// <returns>The built object</returns>
53+
protected abstract TEntity BuildObject();
3754

55+
/// <summary>
56+
/// Return an NSubstitute proxy object when .Build() is called rather than a real object.
57+
/// </summary>
58+
/// <returns>The builder so that other method calls can be chained</returns>
59+
public TBuilder AsProxy()
60+
{
61+
_proxyBuilder = new ProxyBuilder<TEntity>(_properties);
62+
return this as TBuilder;
63+
}
64+
65+
/// <summary>
66+
/// Alter the proxy object just after it has been built and before it's returned from .Build().
67+
/// This allows you to add any .Returns() values that are more complex than the public properties that are proxied by default.
68+
/// </summary>
69+
/// <param name="proxy">The proxy object</param>
70+
protected virtual void AlterProxy(TEntity proxy) {}
71+
3872
/// <summary>
3973
/// Records the given value for the given property from <see cref="TEntity"/>.
4074
/// </summary>

0 commit comments

Comments
 (0)