diff --git a/src/HttpMock.Integration.Tests/MultipleTestsUsingTheSameStubServerWithDifferentHttpMethods.cs b/src/HttpMock.Integration.Tests/MultipleTestsUsingTheSameStubServerWithDifferentHttpMethods.cs index 5848b6e..10f3e23 100644 --- a/src/HttpMock.Integration.Tests/MultipleTestsUsingTheSameStubServerWithDifferentHttpMethods.cs +++ b/src/HttpMock.Integration.Tests/MultipleTestsUsingTheSameStubServerWithDifferentHttpMethods.cs @@ -102,6 +102,19 @@ public void If_no_Mocked_Endpoints_matched_then_should_return_404_with_HttpMockE } } + [Test] + public void Should_return_dynamic_data() + { + string value = "test1"; + _httpMockRepository + .Stub(x => x.Get("/endpoint")) + .Return(() => value) + .OK(); + AssertResponse("GET", "test1"); + value = "test2"; + AssertResponse("GET", "test2"); + } + private void AssertResponse(string method, string expected) { var webRequest = (HttpWebRequest) WebRequest.Create(_endpointToHit); diff --git a/src/HttpMock/BufferedBody.cs b/src/HttpMock/BufferedBody.cs index 621526d..0c1e2c4 100644 --- a/src/HttpMock/BufferedBody.cs +++ b/src/HttpMock/BufferedBody.cs @@ -7,29 +7,29 @@ namespace HttpMock { class BufferedBody : IResponse { - ArraySegment data; + readonly Func dataFunc; public BufferedBody(string data) : this(data, Encoding.UTF8) { } public BufferedBody(string data, Encoding encoding) : this(encoding.GetBytes(data)) { } - public BufferedBody(byte[] data) : this(new ArraySegment(data)) { } - public BufferedBody(ArraySegment data) + public BufferedBody(byte[] data) : this(() => data) { } + public BufferedBody(Func data) : this(() => Encoding.UTF8.GetBytes(data())) { } + public BufferedBody(Func data) { - this.data = data; - Length = data.Count; + this.dataFunc = data; } - public int Length { get; private set; } + public Func Length => () => dataFunc().Length; - public IDisposable Connect(IDataConsumer channel) + public IDisposable Connect(IDataConsumer channel) { // null continuation, consumer must swallow the data immediately. - channel.OnData(data, null); + var bytes = new ArraySegment(dataFunc()); + channel.OnData(bytes, null); channel.OnEnd(); return null; } public void SetRequestHeaders(IDictionary requestHeaders) { - } } @@ -40,7 +40,6 @@ public IDisposable Connect(IDataConsumer channel) { } public void SetRequestHeaders(IDictionary requestHeaders) { - } } } \ No newline at end of file diff --git a/src/HttpMock/IRequestStub.cs b/src/HttpMock/IRequestStub.cs index 3f0f678..9fdd373 100644 --- a/src/HttpMock/IRequestStub.cs +++ b/src/HttpMock/IRequestStub.cs @@ -7,6 +7,7 @@ namespace HttpMock public interface IRequestStub { IRequestStub Return(string responseBody); + IRequestStub Return(Func responseBody); IRequestStub ReturnFile(string pathToFile); IRequestStub WithParams(IDictionary nameValueCollection); void OK(); diff --git a/src/HttpMock/RequestHandler.cs b/src/HttpMock/RequestHandler.cs index a6b483d..3240f83 100644 --- a/src/HttpMock/RequestHandler.cs +++ b/src/HttpMock/RequestHandler.cs @@ -8,10 +8,10 @@ namespace HttpMock { - public class RequestHandler : IRequestHandler, IRequestStub, IRequestVerify - { + public class RequestHandler : IRequestHandler, IRequestStub, IRequestVerify + { private readonly ResponseBuilder _webResponseBuilder = new ResponseBuilder(); - private readonly IList> _constraints = new List>(); + private readonly IList> _constraints = new List>(); private readonly Queue _observedRequests = new Queue(); public RequestHandler(string path, IRequestProcessor requestProcessor) { @@ -34,16 +34,21 @@ public IRequestStub Return(string responseBody) { return this; } + public IRequestStub Return(Func responseBody) { + _webResponseBuilder.Return(responseBody); + return this; + } + public IRequestStub ReturnFile(string pathToFile) { _webResponseBuilder.WithFile(pathToFile); - + return this; } public IRequestStub ReturnFileRange(string pathToFile, int from, int to) { _webResponseBuilder.WithFileRange(pathToFile, from, to); - + return this; } @@ -80,10 +85,10 @@ public IRequestStub AddHeader(string header, string headerValue) { } public IRequestStub WithUrlConstraint(Func constraint) - { - _constraints.Add(constraint); - return this; - } + { + _constraints.Add(constraint); + return this; + } public override string ToString() { var sb = new StringBuilder(); @@ -107,10 +112,10 @@ public string GetBody() { return _observedRequests.Peek().Body; } - public bool CanVerifyConstraintsFor(string url) - { - return _constraints.All(c => c(url)); - } + public bool CanVerifyConstraintsFor(string url) + { + return _constraints.All(c => c(url)); + } public ReceivedRequest LastRequest() { diff --git a/src/HttpMock/ResponseBuilder.cs b/src/HttpMock/ResponseBuilder.cs index fd45569..0ad9f9f 100644 --- a/src/HttpMock/ResponseBuilder.cs +++ b/src/HttpMock/ResponseBuilder.cs @@ -13,14 +13,22 @@ public class ResponseBuilder private HttpStatusCode _httpStatusCode = HttpStatusCode.OK; private string _contentType = "text/plain"; private IResponse _response = new BufferedBody(""); - private int _contentLength = 0; + private Func _contentLength = () => 0; private Dictionary _headers = new Dictionary(); public ResponseBuilder Return(string body) { - var bufferedBody = new BufferedBody(body); - _contentLength = bufferedBody.Length; - _response = bufferedBody; - + var bufferedBody = new BufferedBody(body); + _contentLength = bufferedBody.Length; + _response = bufferedBody; + + return this; + } + + public ResponseBuilder Return(Func body) { + var bufferedBody = new BufferedBody(body); + _contentLength = bufferedBody.Length; + _response = bufferedBody; + return this; } @@ -30,8 +38,8 @@ public IDataProducer BuildBody(IDictionary headers) { } public HttpResponseHead BuildHeaders() { - AddHeader(HttpHeaderNames.ContentType, _contentType); - AddHeader(HttpHeaderNames.ContentLength, _contentLength.ToString()); + AddHeader(HttpHeaderNames.ContentType, _contentType); + AddHeader(HttpHeaderNames.ContentLength, _contentLength().ToString()); var headers = new HttpResponseHead { @@ -39,8 +47,6 @@ public HttpResponseHead BuildHeaders() { Headers = _headers }; return headers; - - } public void WithStatus(HttpStatusCode httpStatusCode) { @@ -54,7 +60,7 @@ public void WithContentType(string contentType) { public void WithFile(string pathToFile) { if(File.Exists(pathToFile)) { var fileInfo = new FileInfo(pathToFile); - _contentLength = (int)fileInfo.Length; + _contentLength = () => (int)fileInfo.Length; _response = new FileResponseBody(pathToFile); } else { throw new InvalidOperationException("File does not exist/accessible at :" + pathToFile); @@ -66,7 +72,7 @@ public void WithFileRange(string pathToFile, int from, int to) if (File.Exists(pathToFile)) { var fileInfo = new FileInfo(pathToFile); - _contentLength = (to - from) +1; + _contentLength = () => (to - from) + 1; _response = new FileResponseBody(pathToFile); AddHeader(HttpResponseHeader.ContentRange.ToString(), string.Format("bytes={0}-{1}/{2}", from, to, fileInfo.Length)); }