Skip to content

Commit 08944ac

Browse files
authored
Merge pull request #14 from ppittle/multiple-creators-per-session
added HttpWebRequestWrapperDelegateCreator
2 parents 1d18010 + ee76511 commit 08944ac

File tree

5 files changed

+142
-0
lines changed

5 files changed

+142
-0
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,25 @@ using(new HttpWebRequestWrapperSession(new CustomWrapperCreator()))
251251
}
252252
```
253253

254+
### Multiple WebRequestCreate
255+
256+
Have an advanced scenario where you need to use multiple `IWebRequestCreate` objects? You can use the `HttpWebRequestWrapperDelegateCreator` to decide just-in-time which `IWebRequestCreate` to use for a specific Uri:
257+
258+
```csharp
259+
var creatorSelector = new Func<Uri, IWebRequestCreate>(url =>
260+
url.Contains("api1")
261+
? api1InterceptorCreator
262+
: commonInterceptorCreator);
263+
264+
using (new HttpWebRequestWrapperSession(new HttpWebRequestWrapperDelegateCreator(creatorSelector)))
265+
{
266+
// handled by api1Interceptor
267+
WebRequest.Create("http://3rdParty.com/api1/request");
268+
// handled by commonInterceptor
269+
WebRequest.Create("http://someother.site");
270+
}
271+
```
272+
254273
## Secret Sauce
255274

256275
**HttpWebRequestWrapper** works by inheriting from `HttpWebRequest`. This doesn't seem revolutionary, except these are the `HttpWebRequest` constructors:
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using System;
2+
using System.Net;
3+
using Moq;
4+
using Should;
5+
using Xunit;
6+
7+
namespace HttpWebRequestWrapper.Tests
8+
{
9+
/// <summary>
10+
/// Tests for <see cref="HttpWebRequestWrapperDelegateCreator"/>
11+
/// </summary>
12+
public class DelegateCreatorTests
13+
{
14+
[Fact]
15+
public void CanUseMultipleWebRequestCreators()
16+
{
17+
// ARRANGE
18+
var url1 = new Uri("http://fakesite.fake/1");
19+
var url2 = new Uri("http://fakesite.fake/2");
20+
21+
var mockRequest1 = new Mock<WebRequest>();
22+
var mockRequest2 = new Mock<WebRequest>();
23+
24+
var mockRequestCreator1 = new Mock<IWebRequestCreate>();
25+
mockRequestCreator1
26+
.Setup(x => x.Create(It.IsAny<Uri>()))
27+
.Returns(mockRequest1.Object);
28+
29+
var mockRequestCreator2 = new Mock<IWebRequestCreate>();
30+
mockRequestCreator2
31+
.Setup(x => x.Create(It.IsAny<Uri>()))
32+
.Returns(mockRequest2.Object);
33+
34+
var creatorSelector = new Func<Uri, IWebRequestCreate>(url =>
35+
url == url1
36+
? mockRequestCreator1.Object
37+
: mockRequestCreator2.Object);
38+
39+
var delegateCreator = new HttpWebRequestWrapperDelegateCreator(creatorSelector);
40+
41+
WebRequest request1, request2;
42+
43+
// ACT
44+
using (new HttpWebRequestWrapperSession(delegateCreator))
45+
{
46+
request1 = WebRequest.Create(url1);
47+
request2 = WebRequest.Create(url2);
48+
}
49+
50+
// ASSERT
51+
request1.ShouldEqual(mockRequest1.Object);
52+
request2.ShouldEqual(mockRequest2.Object);
53+
54+
mockRequestCreator1.Verify(x =>
55+
x.Create(It.Is<Uri>(v => v == url1)),
56+
Times.Once);
57+
mockRequestCreator1.Verify(x =>
58+
x.Create(It.Is<Uri>(v => v == url2)),
59+
Times.Never);
60+
61+
mockRequestCreator2.Verify(x =>
62+
x.Create(It.Is<Uri>(v => v == url1)),
63+
Times.Never);
64+
mockRequestCreator2.Verify(x =>
65+
x.Create(It.Is<Uri>(v => v == url2)),
66+
Times.Once);
67+
}
68+
}
69+
}

src/HttpWebRequestWrapper.Tests/HttpWebRequestWrapper.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
</Reference>
8686
</ItemGroup>
8787
<ItemGroup>
88+
<Compile Include="DelegateCreatorTests.cs" />
8889
<Compile Include="InterceptorTests.cs" />
8990
<Compile Include="Properties\AssemblyInfo.cs" />
9091
<Compile Include="Properties\Extensions.cs" />

src/HttpWebRequestWrapper/HttpWebRequestWrapper.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
<ItemGroup>
5151
<Compile Include="Extensions\RecordedRequestExtensions.cs" />
5252
<Compile Include="Extensions\StringExtensions.cs" />
53+
<Compile Include="HttpWebRequestWrapperDelegateCreator.cs" />
5354
<Compile Include="HttpWebRequestWrapperInterceptor.cs" />
5455
<Compile Include="HttpWebRequestWrapperInterceptorCreator.cs" />
5556
<Compile Include="HttpWebRequestWrapperRecorder.cs" />
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System;
2+
using System.Net;
3+
4+
namespace HttpWebRequestWrapper
5+
{
6+
/// <summary>
7+
/// Helper component that supports just-in-time selection of a
8+
/// <see cref="IWebRequestCreate"/> based on the requested <see cref="Uri"/>.
9+
/// <para />
10+
/// This is only anticipated to be useful when writing BDD style
11+
/// tests that cover a large application surface area - where the system
12+
/// might be making calls to two different api endpoints and it is helpful to
13+
/// have requests be routed to different <see cref="IWebRequestCreate"/>s
14+
/// (ie <see cref="HttpWebRequestWrapperInterceptorCreator"/>) based on url.
15+
/// <para />
16+
/// For example, requests to http://api1/ could go to one Interceptor with a specific
17+
/// <see cref="RecordingSession"/> and playback behavior and requests to http://api2/
18+
/// could go to a different Interceptor with its own <see cref="RecordingSession"/>
19+
/// and different playback behavior.
20+
/// </summary>
21+
public class HttpWebRequestWrapperDelegateCreator : IWebRequestCreate
22+
{
23+
private readonly Func<Uri, IWebRequestCreate> _creatorSelectorFunc;
24+
25+
/// <summary>
26+
/// Helper component that supports just-in-time selection of a
27+
/// <see cref="IWebRequestCreate"/> based on the requested <see cref="Uri"/>
28+
/// via <paramref name="creatorSelector"/>.
29+
/// <para />
30+
/// This is only anticipated to be useful when writing BDD style
31+
/// tests that cover a large application surface area - where the system
32+
/// might be making calls to two different api endpoints and it is helpful to
33+
/// have requests be routed to different <see cref="IWebRequestCreate"/>s
34+
/// (ie <see cref="HttpWebRequestWrapperInterceptorCreator"/>) based on url.
35+
/// <para />
36+
/// For example, requests to http://api1/ could go to one Interceptor with a specific
37+
/// <see cref="RecordingSession"/> and playback behavior and requests to http://api2/
38+
/// could go to a different Interceptor with its own <see cref="RecordingSession"/>
39+
/// and different playback behavior.
40+
/// </summary>
41+
public HttpWebRequestWrapperDelegateCreator(Func<Uri, IWebRequestCreate> creatorSelector)
42+
{
43+
_creatorSelectorFunc = creatorSelector;
44+
}
45+
46+
/// <inheritdoc />
47+
public WebRequest Create(Uri uri)
48+
{
49+
return _creatorSelectorFunc(uri).Create(uri);
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)