Skip to content

Commit

Permalink
Refactoring tests to WireMock
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeyzimarev committed Apr 3, 2024
1 parent 7d8f957 commit 56a1161
Show file tree
Hide file tree
Showing 20 changed files with 396 additions and 370 deletions.
87 changes: 44 additions & 43 deletions Directory.Packages.props
@@ -1,45 +1,46 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<PropertyGroup Label="Package versions for .NET 6" Condition="$(TargetFramework) == 'net6.0'">
<MicrosoftTestHostVer>[6.0.28,7)</MicrosoftTestHostVer>
</PropertyGroup>
<PropertyGroup Label="Package versions for .NET 7" Condition="$(TargetFramework) == 'net7.0'">
<MicrosoftTestHostVer>7.0.17</MicrosoftTestHostVer>
</PropertyGroup>
<PropertyGroup Label="Package versions for .NET 8" Condition="$(TargetFramework) == 'net8.0'">
<MicrosoftTestHostVer>8.0.3</MicrosoftTestHostVer>
</PropertyGroup>
<ItemGroup Label="Runtime dependencies">
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3"/>
<PackageVersion Include="CsvHelper" Version="30.0.1"/>
<PackageVersion Include="System.Text.Json" Version="8.0.3"/>
</ItemGroup>
<ItemGroup Label="Compile dependencies">
<PackageVersion Include="BenchmarkDotNet" Version="0.13.12"/>
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2"/>
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4"/>
<PackageVersion Include="MinVer" Version="5.0.0"/>
<PackageVersion Include="Nullable" Version="1.3.1"/>
<PackageVersion Include="Microsoft.NETFramework.ReferenceAssemblies.net472" Version="1.0.3"/>
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0"/>
<PackageVersion Include="JetBrains.Annotations" Version="2023.2.0"/>
</ItemGroup>
<ItemGroup Label="Testing dependencies">
<PackageVersion Include="AutoFixture" Version="4.18.0"/>
<PackageVersion Include="coverlet.collector" Version="6.0.2"/>
<PackageVersion Include="FluentAssertions" Version="6.12.0"/>
<PackageVersion Include="HttpTracer" Version="2.1.1"/>
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="$(MicrosoftTestHostVer)"/>
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0"/>
<PackageVersion Include="Moq" Version="4.20.69"/>
<PackageVersion Include="Polly" Version="8.3.1"/>
<PackageVersion Include="rest-mock-core" Version="0.7.12"/>
<PackageVersion Include="RichardSzalay.MockHttp" Version="7.0.0"/>
<PackageVersion Include="System.Net.Http.Json" Version="8.0.0"/>
<PackageVersion Include="Xunit.Extensions.Logging" Version="1.1.0"/>
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.7" PrivateAssets="All"/>
<PackageVersion Include="xunit" Version="2.7.0"/>
</ItemGroup>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<PropertyGroup Label="Package versions for .NET 6" Condition="$(TargetFramework) == 'net6.0'">
<MicrosoftTestHostVer>[6.0.28,7)</MicrosoftTestHostVer>
</PropertyGroup>
<PropertyGroup Label="Package versions for .NET 7" Condition="$(TargetFramework) == 'net7.0'">
<MicrosoftTestHostVer>7.0.17</MicrosoftTestHostVer>
</PropertyGroup>
<PropertyGroup Label="Package versions for .NET 8" Condition="$(TargetFramework) == 'net8.0'">
<MicrosoftTestHostVer>8.0.3</MicrosoftTestHostVer>
</PropertyGroup>
<ItemGroup Label="Runtime dependencies">
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="CsvHelper" Version="30.0.1" />
<PackageVersion Include="System.Text.Json" Version="8.0.3" />
<PackageVersion Include="WireMock.Net.FluentAssertions" Version="1.5.51" />
</ItemGroup>
<ItemGroup Label="Compile dependencies">
<PackageVersion Include="BenchmarkDotNet" Version="0.13.12" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="MinVer" Version="5.0.0" />
<PackageVersion Include="Nullable" Version="1.3.1" />
<PackageVersion Include="Microsoft.NETFramework.ReferenceAssemblies.net472" Version="1.0.3" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="JetBrains.Annotations" Version="2023.2.0" />
</ItemGroup>
<ItemGroup Label="Testing dependencies">
<PackageVersion Include="AutoFixture" Version="4.18.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
<PackageVersion Include="FluentAssertions" Version="6.12.0" />
<PackageVersion Include="HttpTracer" Version="2.1.1" />
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="$(MicrosoftTestHostVer)" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageVersion Include="Moq" Version="4.20.69" />
<PackageVersion Include="Polly" Version="8.3.1" />
<PackageVersion Include="rest-mock-core" Version="0.7.12" />
<PackageVersion Include="RichardSzalay.MockHttp" Version="7.0.0" />
<PackageVersion Include="System.Net.Http.Json" Version="8.0.0" />
<PackageVersion Include="Xunit.Extensions.Logging" Version="1.1.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.7" PrivateAssets="All" />
<PackageVersion Include="xunit" Version="2.7.0" />
</ItemGroup>
</Project>
62 changes: 36 additions & 26 deletions test/RestSharp.Tests.Integrated/CompressionTests.cs
@@ -1,59 +1,69 @@
using System.IO.Compression;
using System.Net;
using RestSharp.Extensions;
using RestSharp.Tests.Shared.Extensions;
using RestSharp.Tests.Shared.Fixtures;

namespace RestSharp.Tests.Integrated;
namespace RestSharp.Tests.Integrated;

public class CompressionTests {
static Action<HttpListenerContext> GzipEchoValue(string value)
=> context => {
context.Response.Headers.Add("Content-encoding", "gzip");
static async Task<byte[]> GetBody(Func<Stream, Stream> getStream, string value) {
using var memoryStream = new MemoryStream();

using var gzip = new GZipStream(context.Response.OutputStream, CompressionMode.Compress, true);
await using (var stream = getStream(memoryStream)) {
stream.WriteStringUtf8(value);
}

gzip.WriteStringUtf8(value);
};

static Action<HttpListenerContext> DeflateEchoValue(string value)
=> context => {
context.Response.Headers.Add("Content-encoding", "deflate");
using var gzip = new DeflateStream(context.Response.OutputStream, CompressionMode.Compress, true);
memoryStream.Seek(0, SeekOrigin.Begin);
var body = await memoryStream.ReadAsBytes(default);
return body;
}

gzip.WriteStringUtf8(value);
};
static void ConfigureServer(WireMockServer server, byte[] body, string encoding)
=> server
.Given(Request.Create().WithPath("/").UsingGet())
.RespondWith(Response.Create().WithBody(body).WithHeader("Content-Encoding", encoding));

[Fact]
public async Task Can_Handle_Deflate_Compressed_Content() {
using var server = SimpleServer.Create(DeflateEchoValue("This is some deflated content"));
const string value = "This is some deflated content";
using var server = WireMockServer.Start();

var body = await GetBody(s => new DeflateStream(s, CompressionMode.Compress, true), value);
ConfigureServer(server, body, "deflate");

var client = new RestClient(server.Url);
var client = new RestClient(server.Url!);
var request = new RestRequest("");
var response = await client.ExecuteAsync(request);

Assert.Equal("This is some deflated content", response.Content);
response.Content.Should().Be(value);
}

[Fact]
public async Task Can_Handle_Gzip_Compressed_Content() {
using var server = SimpleServer.Create(GzipEchoValue("This is some gzipped content"));
const string value = "This is some gzipped content";
using var server = WireMockServer.Start();

var body = await GetBody(s => new GZipStream(s, CompressionMode.Compress, true), value);
ConfigureServer(server, body, "gzip");

var client = new RestClient(server.Url);
var client = new RestClient(server.Url!);
var request = new RestRequest("");
var response = await client.ExecuteAsync(request);

Assert.Equal("This is some gzipped content", response.Content);
response.Content.Should().Be(value);
}

[Fact]
public async Task Can_Handle_Uncompressed_Content() {
using var server = SimpleServer.Create(Handlers.EchoValue("This is some sample content"));
const string value = "This is some sample content";
using var server = WireMockServer.Start();
server
.Given(Request.Create().WithPath("/").UsingGet())
.RespondWith(Response.Create().WithBody(value));

var client = new RestClient(server.Url);
var client = new RestClient(server.Url!);
var request = new RestRequest("");
var response = await client.ExecuteAsync(request);

Assert.Equal("This is some sample content", response.Content);
response.Content.Should().Be(value);
}
}
33 changes: 13 additions & 20 deletions test/RestSharp.Tests.Integrated/DefaultParameterTests.cs
@@ -1,51 +1,44 @@
using System.Net;
using RestSharp.Tests.Integrated.Fixtures;
using RestSharp.Tests.Integrated.Server;
using RestSharp.Tests.Shared.Fixtures;

namespace RestSharp.Tests.Integrated;

[Collection(nameof(TestServerCollection))]
public sealed class DefaultParameterTests(TestServerFixture fixture) : IDisposable {
readonly SimpleServer _server = SimpleServer.Create(RequestHandler.Handle);
public sealed class DefaultParameterTests : IDisposable {
readonly WireMockServer _server = WireMockServer.Start();
readonly RequestBodyCapturer _capturer;

public DefaultParameterTests() => _capturer = _server.ConfigureBodyCapturer(Method.Get, false);

public void Dispose() => _server.Dispose();

[Fact]
public async Task Should_add_default_and_request_query_get_parameters() {
var client = new RestClient(_server.Url).AddDefaultParameter("foo", "bar", ParameterType.QueryString);
var request = new RestRequest().AddParameter("foo1", "bar1", ParameterType.QueryString);
var client = new RestClient(_server.Url!).AddDefaultParameter("foo", "bar", ParameterType.QueryString);
var request = new RestRequest().AddParameter("foo1", "bar1", ParameterType.QueryString);

await client.GetAsync(request);

var query = RequestHandler.Url!.Query;
var query = _capturer.Url!.Query;
query.Should().Contain("foo=bar");
query.Should().Contain("foo1=bar1");
}

[Fact]
public async Task Should_add_default_and_request_url_get_parameters() {
var client = new RestClient($"{_server.Url}{{foo}}/").AddDefaultParameter("foo", "bar", ParameterType.UrlSegment);
var client = new RestClient($"{_server.Url}/{{foo}}/").AddDefaultParameter("foo", "bar", ParameterType.UrlSegment);
var request = new RestRequest("{foo1}").AddParameter("foo1", "bar1", ParameterType.UrlSegment);

await client.GetAsync(request);

RequestHandler.Url!.Segments.Should().BeEquivalentTo("/", "bar/", "bar1");
_capturer.Url!.Segments.Should().BeEquivalentTo("/", "bar/", "bar1");
}

[Fact]
public async Task Should_not_throw_exception_when_name_is_null() {
var client = new RestClient($"{fixture.Server.Url}/request-echo").AddDefaultParameter("foo", "bar", ParameterType.UrlSegment);
var client = new RestClient($"{_server.Url}/request-echo").AddDefaultParameter("foo", "bar", ParameterType.UrlSegment);
var request = new RestRequest("{foo1}").AddParameter(null, "value", ParameterType.RequestBody);

await client.ExecuteAsync(request);
}

static class RequestHandler {
public static Uri? Url { get; private set; }

public static void Handle(HttpListenerContext context) {
Url = context.Request.Url;
Handlers.Echo(context);
}
}
}
}
29 changes: 29 additions & 0 deletions test/RestSharp.Tests.Integrated/Fixtures/RequestBodyCapturer.cs
@@ -0,0 +1,29 @@
namespace RestSharp.Tests.Integrated.Fixtures;

class RequestBodyCapturer {
public const string Resource = "/capture";

public string? ContentType { get; private set; }
public bool HasBody { get; private set; }
public string? Body { get; private set; }
public Uri? Url { get; private set; }

public bool CaptureBody(string? content) {
Body = content;
HasBody = !string.IsNullOrWhiteSpace(content);
return true;
}

public bool CaptureHeaders(IDictionary<string, string[]> headers) {
if (headers.TryGetValue("Content-Type", out var contentType)) {
ContentType = contentType[0];
}

return true;
}

public bool CaptureUrl(string url) {
Url = new Uri(url);
return true;
}
}
11 changes: 0 additions & 11 deletions test/RestSharp.Tests.Integrated/Fixtures/RequestBodyFixture.cs

This file was deleted.

17 changes: 17 additions & 0 deletions test/RestSharp.Tests.Integrated/Fixtures/WireMockExtensions.cs
@@ -0,0 +1,17 @@
namespace RestSharp.Tests.Integrated.Fixtures;

static class WireMockExtensions {
public static RequestBodyCapturer ConfigureBodyCapturer(this WireMockServer server, Method method, bool usePath = true) {
var capturer = new RequestBodyCapturer();

var requestBuilder = Request
.Create()
.WithPath(usePath ? RequestBodyCapturer.Resource : "/")
.WithUrl(capturer.CaptureUrl)
.WithBody(capturer.CaptureBody)
.WithHeader(capturer.CaptureHeaders)
.UsingMethod(method.ToString().ToUpper());
server.Given(requestBuilder).RespondWith(Response.Create().WithStatusCode(200));
return capturer;
}
}
31 changes: 18 additions & 13 deletions test/RestSharp.Tests.Integrated/JsonBodyTests.cs
@@ -1,37 +1,41 @@
using System.Text.Json;
using RestSharp.Tests.Integrated.Fixtures;
using RestSharp.Tests.Shared.Fixtures;

namespace RestSharp.Tests.Integrated;

#pragma warning disable xUnit1033
public sealed class JsonBodyTests(RequestBodyFixture fixture) : IClassFixture<RequestBodyFixture> {
readonly SimpleServer _server = fixture.Server;
readonly RestClient _client = new(fixture.Server.Url);
public sealed class JsonBodyTests {
readonly WireMockServer _server = WireMockServer.Start();
readonly RestClient _client;

public JsonBodyTests() => _client = new RestClient(_server.Url!);

[Fact]
public async Task Query_Parameters_With_Json_Body() {
var capturer = _server.ConfigureBodyCapturer(Method.Put);

var request = new RestRequest(RequestBodyCapturer.Resource, Method.Put)
.AddJsonBody(new { displayName = "Display Name" })
.AddQueryParameter("key", "value");

await _client.ExecuteAsync(request);

RequestBodyCapturer.CapturedUrl.ToString().Should().Be($"{_server.Url}Capture?key=value");
RequestBodyCapturer.CapturedContentType.Should().Be("application/json; charset=utf-8");
RequestBodyCapturer.CapturedEntityBody.Should().Be("{\"displayName\":\"Display Name\"}");
capturer.ContentType.Should().Be("application/json; charset=utf-8");
capturer.Body.Should().Be("{\"displayName\":\"Display Name\"}");
capturer.Url.Should().Be($"{_server.Url}{RequestBodyCapturer.Resource}?key=value");
}

[Fact]
public async Task Add_JSON_body_JSON_string() {
const string payload = "{\"displayName\":\"Display Name\"}";

var request = new RestRequest(RequestBodyCapturer.Resource, Method.Post).AddJsonBody(payload);
var capturer = _server.ConfigureBodyCapturer(Method.Post);
var request = new RestRequest(RequestBodyCapturer.Resource, Method.Post).AddJsonBody(payload);

await _client.ExecuteAsync(request);

RequestBodyCapturer.CapturedContentType.Should().Be("application/json; charset=utf-8");
RequestBodyCapturer.CapturedEntityBody.Should().Be(payload);
capturer.ContentType.Should().Be("application/json; charset=utf-8");
capturer.Body.Should().Be(payload);
}

[Fact]
Expand All @@ -48,11 +52,12 @@ public sealed class JsonBodyTests(RequestBodyFixture fixture) : IClassFixture<Re
},";

var expected = JsonSerializer.Serialize(payload);
var capturer = _server.ConfigureBodyCapturer(Method.Post);
var request = new RestRequest(RequestBodyCapturer.Resource, Method.Post).AddJsonBody(payload, true);

await _client.ExecuteAsync(request);

RequestBodyCapturer.CapturedContentType.Should().Be("application/json; charset=utf-8");
RequestBodyCapturer.CapturedEntityBody.Should().Be(expected);
capturer.ContentType.Should().Be("application/json; charset=utf-8");
capturer.Body.Should().Be(expected);
}
}
}

0 comments on commit 56a1161

Please sign in to comment.