From ee76511a2236136aaea09892cefbfe2395ee0a01 Mon Sep 17 00:00:00 2001 From: Philip Pittle Date: Mon, 19 Feb 2018 18:09:30 -0800 Subject: [PATCH] added HttpWebRequestWrapperDelegateCreator --- README.md | 19 +++++ .../DelegateCreatorTests.cs | 69 +++++++++++++++++++ .../HttpWebRequestWrapper.Tests.csproj | 1 + .../HttpWebRequestWrapper.csproj | 1 + .../HttpWebRequestWrapperDelegateCreator.cs | 52 ++++++++++++++ 5 files changed, 142 insertions(+) create mode 100644 src/HttpWebRequestWrapper.Tests/DelegateCreatorTests.cs create mode 100644 src/HttpWebRequestWrapper/HttpWebRequestWrapperDelegateCreator.cs diff --git a/README.md b/README.md index 938eac5..eeeb3c6 100644 --- a/README.md +++ b/README.md @@ -251,6 +251,25 @@ using(new HttpWebRequestWrapperSession(new CustomWrapperCreator())) } ``` +### Multiple WebRequestCreate + +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: + +```csharp +var creatorSelector = new Func(url => + url.Contains("api1") + ? api1InterceptorCreator + : commonInterceptorCreator); + +using (new HttpWebRequestWrapperSession(new HttpWebRequestWrapperDelegateCreator(creatorSelector))) +{ + // handled by api1Interceptor + WebRequest.Create("http://3rdParty.com/api1/request"); + // handled by commonInterceptor + WebRequest.Create("http://someother.site"); +} +``` + ## Secret Sauce **HttpWebRequestWrapper** works by inheriting from `HttpWebRequest`. This doesn't seem revolutionary, except these are the `HttpWebRequest` constructors: diff --git a/src/HttpWebRequestWrapper.Tests/DelegateCreatorTests.cs b/src/HttpWebRequestWrapper.Tests/DelegateCreatorTests.cs new file mode 100644 index 0000000..a8757d1 --- /dev/null +++ b/src/HttpWebRequestWrapper.Tests/DelegateCreatorTests.cs @@ -0,0 +1,69 @@ +using System; +using System.Net; +using Moq; +using Should; +using Xunit; + +namespace HttpWebRequestWrapper.Tests +{ + /// + /// Tests for + /// + public class DelegateCreatorTests + { + [Fact] + public void CanUseMultipleWebRequestCreators() + { + // ARRANGE + var url1 = new Uri("http://fakesite.fake/1"); + var url2 = new Uri("http://fakesite.fake/2"); + + var mockRequest1 = new Mock(); + var mockRequest2 = new Mock(); + + var mockRequestCreator1 = new Mock(); + mockRequestCreator1 + .Setup(x => x.Create(It.IsAny())) + .Returns(mockRequest1.Object); + + var mockRequestCreator2 = new Mock(); + mockRequestCreator2 + .Setup(x => x.Create(It.IsAny())) + .Returns(mockRequest2.Object); + + var creatorSelector = new Func(url => + url == url1 + ? mockRequestCreator1.Object + : mockRequestCreator2.Object); + + var delegateCreator = new HttpWebRequestWrapperDelegateCreator(creatorSelector); + + WebRequest request1, request2; + + // ACT + using (new HttpWebRequestWrapperSession(delegateCreator)) + { + request1 = WebRequest.Create(url1); + request2 = WebRequest.Create(url2); + } + + // ASSERT + request1.ShouldEqual(mockRequest1.Object); + request2.ShouldEqual(mockRequest2.Object); + + mockRequestCreator1.Verify(x => + x.Create(It.Is(v => v == url1)), + Times.Once); + mockRequestCreator1.Verify(x => + x.Create(It.Is(v => v == url2)), + Times.Never); + + mockRequestCreator2.Verify(x => + x.Create(It.Is(v => v == url1)), + Times.Never); + mockRequestCreator2.Verify(x => + x.Create(It.Is(v => v == url2)), + Times.Once); + } + } +} \ No newline at end of file diff --git a/src/HttpWebRequestWrapper.Tests/HttpWebRequestWrapper.Tests.csproj b/src/HttpWebRequestWrapper.Tests/HttpWebRequestWrapper.Tests.csproj index c16e68f..64b0f63 100644 --- a/src/HttpWebRequestWrapper.Tests/HttpWebRequestWrapper.Tests.csproj +++ b/src/HttpWebRequestWrapper.Tests/HttpWebRequestWrapper.Tests.csproj @@ -85,6 +85,7 @@ + diff --git a/src/HttpWebRequestWrapper/HttpWebRequestWrapper.csproj b/src/HttpWebRequestWrapper/HttpWebRequestWrapper.csproj index 5fe6c97..772c65f 100644 --- a/src/HttpWebRequestWrapper/HttpWebRequestWrapper.csproj +++ b/src/HttpWebRequestWrapper/HttpWebRequestWrapper.csproj @@ -50,6 +50,7 @@ + diff --git a/src/HttpWebRequestWrapper/HttpWebRequestWrapperDelegateCreator.cs b/src/HttpWebRequestWrapper/HttpWebRequestWrapperDelegateCreator.cs new file mode 100644 index 0000000..5c27a39 --- /dev/null +++ b/src/HttpWebRequestWrapper/HttpWebRequestWrapperDelegateCreator.cs @@ -0,0 +1,52 @@ +using System; +using System.Net; + +namespace HttpWebRequestWrapper +{ + /// + /// Helper component that supports just-in-time selection of a + /// based on the requested . + /// + /// This is only anticipated to be useful when writing BDD style + /// tests that cover a large application surface area - where the system + /// might be making calls to two different api endpoints and it is helpful to + /// have requests be routed to different s + /// (ie ) based on url. + /// + /// For example, requests to http://api1/ could go to one Interceptor with a specific + /// and playback behavior and requests to http://api2/ + /// could go to a different Interceptor with its own + /// and different playback behavior. + /// + public class HttpWebRequestWrapperDelegateCreator : IWebRequestCreate + { + private readonly Func _creatorSelectorFunc; + + /// + /// Helper component that supports just-in-time selection of a + /// based on the requested + /// via . + /// + /// This is only anticipated to be useful when writing BDD style + /// tests that cover a large application surface area - where the system + /// might be making calls to two different api endpoints and it is helpful to + /// have requests be routed to different s + /// (ie ) based on url. + /// + /// For example, requests to http://api1/ could go to one Interceptor with a specific + /// and playback behavior and requests to http://api2/ + /// could go to a different Interceptor with its own + /// and different playback behavior. + /// + public HttpWebRequestWrapperDelegateCreator(Func creatorSelector) + { + _creatorSelectorFunc = creatorSelector; + } + + /// + public WebRequest Create(Uri uri) + { + return _creatorSelectorFunc(uri).Create(uri); + } + } +} \ No newline at end of file