From 26392cdd2028eff2132948d5cc5e36e08a2d69a9 Mon Sep 17 00:00:00 2001 From: 杨宇千 Date: Sun, 11 Aug 2019 15:34:59 +0800 Subject: Add FluentAssertions. --- .../Helpers/AssertionResponseExtensions.cs | 114 +++++++++++++++++++++ .../Authentication/AuthenticationExtensions.cs | 2 +- Timeline.Tests/Helpers/InvalidModelTestHelpers.cs | 12 +-- Timeline.Tests/Helpers/ResponseExtensions.cs | 61 ----------- Timeline.Tests/Helpers/UserInfoComparers.cs | 47 --------- 5 files changed, 119 insertions(+), 117 deletions(-) create mode 100644 Timeline.Tests/Helpers/AssertionResponseExtensions.cs delete mode 100644 Timeline.Tests/Helpers/ResponseExtensions.cs delete mode 100644 Timeline.Tests/Helpers/UserInfoComparers.cs (limited to 'Timeline.Tests/Helpers') diff --git a/Timeline.Tests/Helpers/AssertionResponseExtensions.cs b/Timeline.Tests/Helpers/AssertionResponseExtensions.cs new file mode 100644 index 00000000..b56340ea --- /dev/null +++ b/Timeline.Tests/Helpers/AssertionResponseExtensions.cs @@ -0,0 +1,114 @@ +using FluentAssertions; +using FluentAssertions.Execution; +using FluentAssertions.Primitives; +using Newtonsoft.Json; +using System; +using System.Net; +using System.Net.Http; +using Timeline.Models.Http; + +namespace Timeline.Tests.Helpers +{ + public class HttpResponseMessageAssertions + : ReferenceTypeAssertions + { + public HttpResponseMessageAssertions(HttpResponseMessage instance) + { + Subject = instance; + } + + protected override string Identifier => "HttpResponseMessage"; + + public AndConstraint HaveStatusCode(HttpStatusCode expected, string because = "", params object[] becauseArgs) + { + Execute.Assertion.BecauseOf(because, becauseArgs) + .ForCondition(Subject.StatusCode == expected) + .FailWith("Expected status code is {}, but found {}.", expected, Subject.StatusCode); + return new AndConstraint(Subject); + } + + public AndWhichConstraint HaveBodyAsJson(string because = "", params object[] becauseArgs) + { + var a = Execute.Assertion.BecauseOf(because, becauseArgs); + string body; + try + { + body = Subject.Content.ReadAsStringAsync().Result; + } + catch (Exception e) + { + a.FailWith("Failed to read response body. Exception is {}.", e); + return new AndWhichConstraint(Subject, null); + } + + try + { + var result = JsonConvert.DeserializeObject(body); + return new AndWhichConstraint(Subject, result); + } + catch (Exception e) + { + a.FailWith("Failed to convert response body to {}. Exception is {}.", typeof(T).FullName, e); + return new AndWhichConstraint(Subject, null); + } + } + } + + public static class AssertionResponseExtensions + { + public static HttpResponseMessageAssertions Should(this HttpResponseMessage instance) + { + return new HttpResponseMessageAssertions(instance); + } + + public static AndConstraint HaveStatusCodeOk(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) + { + return assertions.HaveStatusCode(HttpStatusCode.OK, because, becauseArgs); + } + + public static AndConstraint HaveStatusCodeCreated(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) + { + return assertions.HaveStatusCode(HttpStatusCode.Created, because, becauseArgs); + } + + public static AndConstraint HaveStatusCodeBadRequest(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) + { + return assertions.HaveStatusCode(HttpStatusCode.BadRequest, because, becauseArgs); + } + + public static AndConstraint HaveStatusCodeNotFound(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) + { + return assertions.HaveStatusCode(HttpStatusCode.NotFound, because, becauseArgs); + } + + public static AndWhichConstraint HaveBodyAsCommonResponse(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) + { + return assertions.HaveBodyAsJson(because, becauseArgs); + } + + public static void HaveBodyAsCommonResponseWithCode(this HttpResponseMessageAssertions assertions, int expected, string because = "", params object[] becauseArgs) + { + assertions.HaveBodyAsCommonResponse(because, becauseArgs).Which.Code.Should().Be(expected, because, becauseArgs); + } + + public static void BePutCreated(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) + { + assertions.HaveStatusCodeCreated(because, becauseArgs).And.Should().HaveBodyAsCommonResponse(because, becauseArgs).Which.Should().BeEquivalentTo(CommonPutResponse.Created, because, becauseArgs); + } + + public static void BePutModified(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) + { + assertions.HaveStatusCodeOk(because, becauseArgs).And.Should().HaveBodyAsCommonResponse(because, becauseArgs).Which.Should().BeEquivalentTo(CommonPutResponse.Modified, because, becauseArgs); + } + + public static void BeDeleteDeleted(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) + { + assertions.HaveStatusCodeOk(because, becauseArgs).And.Should().HaveBodyAsCommonResponse(because, becauseArgs).Which.Should().BeEquivalentTo(CommonDeleteResponse.Deleted, because, becauseArgs); + } + + public static void BeDeleteNotExist(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) + { + assertions.HaveStatusCodeOk(because, becauseArgs).And.Should().HaveBodyAsCommonResponse(because, becauseArgs).Which.Should().BeEquivalentTo(CommonDeleteResponse.NotExists, because, becauseArgs); + } + } +} diff --git a/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs b/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs index 8a44c852..c8a79e58 100644 --- a/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs +++ b/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs @@ -14,7 +14,7 @@ namespace Timeline.Tests.Helpers.Authentication public static async Task CreateUserTokenAsync(this HttpClient client, string username, string password, int? expireOffset = null) { var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = username, Password = password, ExpireOffset = expireOffset }); - response.AssertOk(); + response.Should().HaveStatusCodeOk(); var result = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); return result; } diff --git a/Timeline.Tests/Helpers/InvalidModelTestHelpers.cs b/Timeline.Tests/Helpers/InvalidModelTestHelpers.cs index 1c079d0e..af432095 100644 --- a/Timeline.Tests/Helpers/InvalidModelTestHelpers.cs +++ b/Timeline.Tests/Helpers/InvalidModelTestHelpers.cs @@ -1,8 +1,6 @@ -using System.Net; using System.Net.Http; using System.Threading.Tasks; using Timeline.Models.Http; -using Xunit; namespace Timeline.Tests.Helpers { @@ -11,17 +9,15 @@ namespace Timeline.Tests.Helpers public static async Task TestPostInvalidModel(HttpClient client, string url, T body) { var response = await client.PostAsJsonAsync(url, body); - Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); - var responseBody = await response.ReadBodyAsJson(); - Assert.Equal(CommonResponse.ErrorCodes.InvalidModel, responseBody.Code); + response.Should().HaveStatusCodeBadRequest() + .And.Should().HaveBodyAsCommonResponseWithCode(CommonResponse.ErrorCodes.InvalidModel); } public static async Task TestPutInvalidModel(HttpClient client, string url, T body) { var response = await client.PutAsJsonAsync(url, body); - Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); - var responseBody = await response.ReadBodyAsJson(); - Assert.Equal(CommonResponse.ErrorCodes.InvalidModel, responseBody.Code); + response.Should().HaveStatusCodeBadRequest() + .And.Should().HaveBodyAsCommonResponseWithCode(CommonResponse.ErrorCodes.InvalidModel); } } } diff --git a/Timeline.Tests/Helpers/ResponseExtensions.cs b/Timeline.Tests/Helpers/ResponseExtensions.cs deleted file mode 100644 index 46c9e81d..00000000 --- a/Timeline.Tests/Helpers/ResponseExtensions.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Newtonsoft.Json; -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; -using Timeline.Models.Http; -using Xunit; - -namespace Timeline.Tests.Helpers -{ - public static class ResponseExtensions - { - public static void AssertOk(this HttpResponseMessage response) - { - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - } - - public static void AssertNotFound(this HttpResponseMessage response) - { - Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); - } - - public static void AssertBadRequest(this HttpResponseMessage response) - { - Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); - } - - public static async Task AssertIsPutCreated(this HttpResponseMessage response) - { - Assert.Equal(HttpStatusCode.Created, response.StatusCode); - var body = await response.ReadBodyAsJson(); - Assert.Equal(CommonPutResponse.CreatedCode, body.Code); - } - - public static async Task AssertIsPutModified(this HttpResponseMessage response) - { - response.AssertOk(); - var body = await response.ReadBodyAsJson(); - Assert.Equal(CommonPutResponse.ModifiedCode, body.Code); - } - - - public static async Task AssertIsDeleteDeleted(this HttpResponseMessage response) - { - response.AssertOk(); - var body = await response.ReadBodyAsJson(); - Assert.Equal(CommonDeleteResponse.DeletedCode, body.Code); - } - - public static async Task AssertIsDeleteNotExist(this HttpResponseMessage response) - { - response.AssertOk(); - var body = await response.ReadBodyAsJson(); - Assert.Equal(CommonDeleteResponse.NotExistsCode, body.Code); - } - - public static async Task ReadBodyAsJson(this HttpResponseMessage response) - { - return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); - } - } -} diff --git a/Timeline.Tests/Helpers/UserInfoComparers.cs b/Timeline.Tests/Helpers/UserInfoComparers.cs deleted file mode 100644 index 1a1c652d..00000000 --- a/Timeline.Tests/Helpers/UserInfoComparers.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Collections.Generic; -using Timeline.Models; - -namespace Timeline.Tests.Helpers -{ - public static class UserInfoComparers - { - public static IEqualityComparer EqualityComparer { get; } = new EqualityComparerImpl(); - public static IComparer Comparer { get; } = Comparer.Create(Compare); - - - private class EqualityComparerImpl : IEqualityComparer - { - bool IEqualityComparer.Equals(UserInfo x, UserInfo y) - { - return Compare(x, y) == 0; - } - - int IEqualityComparer.GetHashCode(UserInfo obj) - { - return obj.Username.GetHashCode() ^ obj.Administrator.GetHashCode(); - } - } - - public static int Compare(UserInfo left, UserInfo right) - { - if (left == null) - { - if (right == null) - return 0; - return -1; - } - - if (right == null) - return 1; - - var uc = string.Compare(left.Username, right.Username); - if (uc != 0) - return uc; - - if (left.Administrator == right.Administrator) - return 0; - - return left.Administrator ? -1 : 1; - } - } -} -- cgit v1.2.3