From cf8e22c40b4522f61028a9d06dabc1ee58bd7464 Mon Sep 17 00:00:00 2001 From: Viktor Faddi <faddiv@gmail.com> Date: Sun, 16 Feb 2020 19:01:35 +0100 Subject: [PATCH 1/6] Add BeJsonResult and WithValue assertions. --- .../ActionResultAssertions.cs | 15 +++++++ .../JsonResultAssertions.cs | 45 +++++++++++++++++++ .../ActionResultAssertions_Tests.cs | 17 +++++++ .../JsonResultAssertions_Tests.cs | 31 +++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs create mode 100644 tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs diff --git a/src/FluentAssertions.AspNetCore.Mvc/ActionResultAssertions.cs b/src/FluentAssertions.AspNetCore.Mvc/ActionResultAssertions.cs index ede6409..908204c 100644 --- a/src/FluentAssertions.AspNetCore.Mvc/ActionResultAssertions.cs +++ b/src/FluentAssertions.AspNetCore.Mvc/ActionResultAssertions.cs @@ -86,6 +86,21 @@ public EmptyResult BeEmptyResult(string reason, params object[] reasonArgs) return Subject as EmptyResult; } + public JsonResultAssertions BeJsonResult() + { + return BeJsonResult(string.Empty, null); + } + + public JsonResultAssertions BeJsonResult(string reason, params object[] reasonArgs) + { + Execute.Assertion + .BecauseOf(reason, reasonArgs) + .ForCondition(Subject is JsonResult) + .FailWith(Constants.CommonFailMessage, typeof(JsonResult).Name, Subject.GetType().Name); + + return new JsonResultAssertions(Subject as JsonResult); + } + /// <summary> /// Asserts that the subject is a <see cref="RedirectToRouteResult"/>. /// </summary> diff --git a/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs b/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs new file mode 100644 index 0000000..5f5b411 --- /dev/null +++ b/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs @@ -0,0 +1,45 @@ +using FluentAssertions.Execution; +using FluentAssertions.Primitives; +using Microsoft.AspNetCore.Mvc; +using System; + +namespace FluentAssertions.AspNetCore.Mvc +{ + public class JsonResultAssertions : ObjectAssertions + { + #region Public Constructors + + public JsonResultAssertions(JsonResult subject) : base(subject) + { + + } + + #endregion + + #region Public Properties + + #endregion + + #region Private Properties + + private JsonResult JsonResultSubject => (JsonResult)Subject; + + #endregion Private Properties + + #region Public Methods + + public JsonResultAssertions WithValue(object expectedValue, string reason = "", + params object[] reasonArgs) + { + var actualValue = JsonResultSubject.Value; + + Execute.Assertion + .ForCondition(Equals(expectedValue, actualValue)) + .BecauseOf(reason, reasonArgs) + .FailWith(FailureMessages.CommonFailMessage, "JsonResult.Value", expectedValue, actualValue); + return this; + } + + #endregion + } +} \ No newline at end of file diff --git a/tests/FluentAssertions.AspNetCore.Mvc.Tests/ActionResultAssertions_Tests.cs b/tests/FluentAssertions.AspNetCore.Mvc.Tests/ActionResultAssertions_Tests.cs index 6cb45ff..b811532 100644 --- a/tests/FluentAssertions.AspNetCore.Mvc.Tests/ActionResultAssertions_Tests.cs +++ b/tests/FluentAssertions.AspNetCore.Mvc.Tests/ActionResultAssertions_Tests.cs @@ -42,6 +42,23 @@ public void BeEmpty_GivenNotEmpty_ShouldPass() .WithMessage("Expected ActionResult to be \"EmptyResult\", but found \"ViewResult\""); } + [Fact] + public void BeJson_GivenJson_ShouldPass() + { + ActionResult result = new JsonResult(new object()); + result.Should() + .BeJsonResult(); + } + + [Fact] + public void BeJson_GivenNotJson_ShouldFail() + { + ActionResult result = new ViewResult(); + Action a = () => result.Should().BeJsonResult(); + a.Should().Throw<Exception>() + .WithMessage("Expected ActionResult to be \"JsonResult\", but found \"ViewResult\""); + } + [Fact] public void BeRedirectToRoute_GivenRedirectToRoute_ShouldPass() { diff --git a/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs b/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs new file mode 100644 index 0000000..afd1bae --- /dev/null +++ b/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs @@ -0,0 +1,31 @@ +using FluentAssertions.Mvc.Tests.Helpers; +using Microsoft.AspNetCore.Mvc; +using System; +using Xunit; + +namespace FluentAssertions.AspNetCore.Mvc.Tests +{ + public class JsonResultAssertions_Tests + { + [Fact] + public void WithValue_GivenValue_ShouldPass() + { + ActionResult result = new JsonResult("value"); + result.Should().BeJsonResult().WithValue("value"); + } + + [Fact] + public void WithValue_GivenUnexpected_ShouldFail() + { + var actualValue = "xyz"; + var expectedValue = "value"; + ActionResult result = new JsonResult(actualValue); + var failureMessage = FailureMessageHelper.Format(FailureMessages.CommonFailMessage, "JsonResult.Value", expectedValue, actualValue); + + Action a = () => result.Should().BeJsonResult().WithValue(expectedValue); + + a.Should().Throw<Exception>() + .WithMessage(failureMessage); + } + } +} \ No newline at end of file From 57519f2fc60c063af9e334e8711d93095778da9b Mon Sep 17 00:00:00 2001 From: Viktor Faddi <faddiv@gmail.com> Date: Mon, 17 Feb 2020 17:55:53 +0100 Subject: [PATCH 2/6] Add comments. --- .../ActionResultAssertions.cs | 13 ++++++++++ .../JsonResultAssertions.cs | 26 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/FluentAssertions.AspNetCore.Mvc/ActionResultAssertions.cs b/src/FluentAssertions.AspNetCore.Mvc/ActionResultAssertions.cs index 908204c..0c45306 100644 --- a/src/FluentAssertions.AspNetCore.Mvc/ActionResultAssertions.cs +++ b/src/FluentAssertions.AspNetCore.Mvc/ActionResultAssertions.cs @@ -86,11 +86,24 @@ public EmptyResult BeEmptyResult(string reason, params object[] reasonArgs) return Subject as EmptyResult; } + /// <summary> + /// Asserts that the subject is an <see cref="JsonResult"/>. + /// </summary> public JsonResultAssertions BeJsonResult() { return BeJsonResult(string.Empty, null); } + /// <summary> + /// Asserts that the subject is an <see cref="JsonResult"/>. + /// </summary> + /// <param name="reason"> + /// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion + /// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. + /// </param> + /// <param name="reasonArgs"> + /// Zero or more objects to format using the placeholders in <see cref="reason" />. + /// </param> public JsonResultAssertions BeJsonResult(string reason, params object[] reasonArgs) { Execute.Assertion diff --git a/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs b/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs index 5f5b411..f022d34 100644 --- a/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs +++ b/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs @@ -2,13 +2,22 @@ using FluentAssertions.Primitives; using Microsoft.AspNetCore.Mvc; using System; +using System.Diagnostics; namespace FluentAssertions.AspNetCore.Mvc { + /// <summary> + /// Contains a number of methods to assert that a <see cref="JsonResult" /> is in the expected state. + /// </summary> + [DebuggerNonUserCode] public class JsonResultAssertions : ObjectAssertions { #region Public Constructors + /// <summary> + /// Initializes a new instance of the <see cref="T:JsonResultAssertions" /> class. + /// </summary> + /// <param name="subject">The object to test assertion on</param> public JsonResultAssertions(JsonResult subject) : base(subject) { @@ -18,6 +27,11 @@ public JsonResultAssertions(JsonResult subject) : base(subject) #region Public Properties + /// <summary> + /// The value on the JsonResult + /// </summary> + public object Value => JsonResultSubject.Value; + #endregion #region Private Properties @@ -28,6 +42,18 @@ public JsonResultAssertions(JsonResult subject) : base(subject) #region Public Methods + /// <summary> + /// Asserts that the value is the expected value using Equals. + /// </summary> + /// <param name="expectedValue">The expected value.</param> + /// <param name="reason"> + /// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion + /// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. + /// </param> + /// <param name="reasonArgs"> + /// Zero or more objects to format using the placeholders in <see cref="reason" />. + /// </param> + /// <returns></returns> public JsonResultAssertions WithValue(object expectedValue, string reason = "", params object[] reasonArgs) { From 8e1333609caf6f546199ea70e2fa5caa2de42247 Mon Sep 17 00:00:00 2001 From: Viktor Faddi <faddiv@gmail.com> Date: Mon, 17 Feb 2020 18:20:07 +0100 Subject: [PATCH 3/6] Add ValueAs to JsonResult --- .../FailureMessages.Designer.cs | 29 ++++++---- .../FailureMessages.resx | 9 ++- .../FluentAssertions.AspNetCore.Mvc.csproj | 15 +++++ .../JsonResultAssertions.cs | 18 ++++++ .../PartialViewResultAssertions.cs | 8 +-- .../ViewResultAssertions.cs | 4 +- .../JsonResultAssertions_Tests.cs | 56 +++++++++++++++++++ .../PartialViewResultAssertions_Tests.cs | 2 +- .../TestController.cs | 5 ++ .../ViewResultAssertions_Tests.cs | 2 +- 10 files changed, 127 insertions(+), 21 deletions(-) diff --git a/src/FluentAssertions.AspNetCore.Mvc/FailureMessages.Designer.cs b/src/FluentAssertions.AspNetCore.Mvc/FailureMessages.Designer.cs index 39e3abe..e86ad24 100644 --- a/src/FluentAssertions.AspNetCore.Mvc/FailureMessages.Designer.cs +++ b/src/FluentAssertions.AspNetCore.Mvc/FailureMessages.Designer.cs @@ -19,7 +19,7 @@ namespace FluentAssertions.AspNetCore.Mvc { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class FailureMessages { @@ -69,6 +69,24 @@ internal static string CommonFailMessage { } } + /// <summary> + /// Looks up a localized string similar to Expected {0} to be of type {1}, but no {0} was supplied.. + /// </summary> + internal static string CommonNullWasSuppliedFailMessage { + get { + return ResourceManager.GetString("CommonNullWasSuppliedFailMessage", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Expected {0} to be of type '{1}' but was '{2}'. + /// </summary> + internal static string CommonTypeFailMessage { + get { + return ResourceManager.GetString("CommonTypeFailMessage", resourceCulture); + } + } + /// <summary> /// Looks up a localized string similar to RedirectToActionResult.RouteValues does not contain key {0}.. /// </summary> @@ -132,15 +150,6 @@ internal static string ViewResult_MasterName { } } - /// <summary> - /// Looks up a localized string similar to Expected Model to be of type {0}, but no Model was supplied.. - /// </summary> - internal static string ViewResultBase_NullModel { - get { - return ResourceManager.GetString("ViewResultBase_NullModel", resourceCulture); - } - } - /// <summary> /// Looks up a localized string similar to ViewData does not contain key of {0}.. /// </summary> diff --git a/src/FluentAssertions.AspNetCore.Mvc/FailureMessages.resx b/src/FluentAssertions.AspNetCore.Mvc/FailureMessages.resx index 2f282e6..d4ffa71 100644 --- a/src/FluentAssertions.AspNetCore.Mvc/FailureMessages.resx +++ b/src/FluentAssertions.AspNetCore.Mvc/FailureMessages.resx @@ -120,6 +120,12 @@ <data name="CommonFailMessage" xml:space="preserve"> <value>Expected {0} to be '{1}' but found '{2}'</value> </data> + <data name="CommonNullWasSuppliedFailMessage" xml:space="preserve"> + <value>Expected {0} to be of type {1}, but no {0} was supplied.</value> + </data> + <data name="CommonTypeFailMessage" xml:space="preserve"> + <value>Expected {0} to be of type '{1}' but was '{2}'</value> + </data> <data name="RedirectToActionResult_RouteValues_ContainsKey" xml:space="preserve"> <value>RedirectToActionResult.RouteValues does not contain key {0}.</value> </data> @@ -138,9 +144,6 @@ <data name="RouteData_Values_HaveValue" xml:space="preserve"> <value>Expected RouteData.Values[{0}] to have value {1}, but found {2}.</value> </data> - <data name="ViewResultBase_NullModel" xml:space="preserve"> - <value>Expected Model to be of type {0}, but no Model was supplied.</value> - </data> <data name="ViewResultBase_ViewData_ContainsKey" xml:space="preserve"> <value>ViewData does not contain key of {0}.</value> </data> diff --git a/src/FluentAssertions.AspNetCore.Mvc/FluentAssertions.AspNetCore.Mvc.csproj b/src/FluentAssertions.AspNetCore.Mvc/FluentAssertions.AspNetCore.Mvc.csproj index 88aca36..7ebd6c9 100644 --- a/src/FluentAssertions.AspNetCore.Mvc/FluentAssertions.AspNetCore.Mvc.csproj +++ b/src/FluentAssertions.AspNetCore.Mvc/FluentAssertions.AspNetCore.Mvc.csproj @@ -29,4 +29,19 @@ <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" /> </ItemGroup> + <ItemGroup> + <Compile Update="FailureMessages.Designer.cs"> + <DesignTime>True</DesignTime> + <AutoGen>True</AutoGen> + <DependentUpon>FailureMessages.resx</DependentUpon> + </Compile> + </ItemGroup> + + <ItemGroup> + <EmbeddedResource Update="FailureMessages.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>FailureMessages.Designer.cs</LastGenOutput> + </EmbeddedResource> + </ItemGroup> + </Project> diff --git a/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs b/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs index f022d34..0b97b2a 100644 --- a/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs +++ b/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs @@ -66,6 +66,24 @@ public JsonResultAssertions WithValue(object expectedValue, string reason = "", return this; } + /// <summary> + /// Asserts the value is of the expected type. + /// </summary> + /// <typeparam name="TValue">The expected type.</typeparam> + /// <returns>The typed value.</returns> + public TValue ValueAs<TValue>() + { + var value = JsonResultSubject.Value; + + if (value == null) + Execute.Assertion.FailWith(FailureMessages.CommonNullWasSuppliedFailMessage, "Value", typeof(TValue).Name); + + Execute.Assertion + .ForCondition(value is TValue) + .FailWith(FailureMessages.CommonTypeFailMessage, "Value", typeof(TValue).Name, value.GetType().Name); + + return (TValue)value; + } #endregion } } \ No newline at end of file diff --git a/src/FluentAssertions.AspNetCore.Mvc/PartialViewResultAssertions.cs b/src/FluentAssertions.AspNetCore.Mvc/PartialViewResultAssertions.cs index 4f631eb..c727677 100644 --- a/src/FluentAssertions.AspNetCore.Mvc/PartialViewResultAssertions.cs +++ b/src/FluentAssertions.AspNetCore.Mvc/PartialViewResultAssertions.cs @@ -15,7 +15,7 @@ public PartialViewResultAssertions(PartialViewResult subject) : base(subject) { } - private PartialViewResult PartialViewResultSubject => (PartialViewResult) Subject; + private PartialViewResult PartialViewResultSubject => (PartialViewResult)Subject; /// <summary> /// The model. @@ -114,13 +114,13 @@ public TModel ModelAs<TModel>() var model = PartialViewResultSubject.ViewData?.Model; if (model == null) - Execute.Assertion.FailWith(FailureMessages.ViewResultBase_NullModel, typeof(TModel).Name); + Execute.Assertion.FailWith(FailureMessages.CommonNullWasSuppliedFailMessage, "Model", typeof(TModel).Name); Execute.Assertion .ForCondition(model is TModel) - .FailWith("Expected Model to be of type '{0}' but was '{1}'", typeof(TModel).Name, model.GetType().Name); + .FailWith(FailureMessages.CommonTypeFailMessage, "Model", typeof(TModel).Name, model.GetType().Name); - return (TModel) model; + return (TModel)model; } /// <summary> diff --git a/src/FluentAssertions.AspNetCore.Mvc/ViewResultAssertions.cs b/src/FluentAssertions.AspNetCore.Mvc/ViewResultAssertions.cs index ca5c940..099adf3 100644 --- a/src/FluentAssertions.AspNetCore.Mvc/ViewResultAssertions.cs +++ b/src/FluentAssertions.AspNetCore.Mvc/ViewResultAssertions.cs @@ -133,11 +133,11 @@ public TModel ModelAs<TModel>() var model = ViewResultSubject.Model; if (model == null) - Execute.Assertion.FailWith(FailureMessages.ViewResultBase_NullModel, typeof(TModel).Name); + Execute.Assertion.FailWith(FailureMessages.CommonNullWasSuppliedFailMessage, "Model", typeof(TModel).Name); Execute.Assertion .ForCondition(model is TModel) - .FailWith("Expected Model to be of type '{0}' but was '{1}'", typeof(TModel).Name, model.GetType().Name); + .FailWith(FailureMessages.CommonTypeFailMessage, "Model", typeof(TModel).Name, model.GetType().Name); return (TModel)model; } diff --git a/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs b/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs index afd1bae..baff4c2 100644 --- a/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs +++ b/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs @@ -27,5 +27,61 @@ public void WithValue_GivenUnexpected_ShouldFail() a.Should().Throw<Exception>() .WithMessage(failureMessage); } + + [Fact] + public void Value_GivenExpectedValue_ShouldPass() + { + var result = new TestController().JsonSimpleValue(); + + result.Should().BeJsonResult().Value.Should().Be("hello"); + } + + [Fact] + public void Json_GivenUnexpectedValue_ShouldFail() + { + var result = new TestController().JsonSimpleValue(); + + Action a = () => result.Should().BeJsonResult().Value.Should().Be("xyx"); + a.Should().Throw<Exception>(); + } + + [Fact] + public void ValueAs_GivenExpectedValue_ShouldPass() + { + var result = new TestController().JsonSimpleValue(); + + result.Should().BeJsonResult().ValueAs<string>().Should().Be("hello"); + } + + [Fact] + public void ValueAs_GivenUnexpectedValue_ShouldFail() + { + var result = new TestController().JsonSimpleValue(); + + Action a = () => result.Should().BeJsonResult().ValueAs<string>().Should().Be("xyx"); + a.Should().Throw<Exception>(); + } + + [Fact] + public void ValueAs_GivenWrongType_ShouldFail() + { + var result = new TestController().JsonSimpleValue(); + + Action a = () => result.Should().BeJsonResult().ValueAs<int>().Should().Be(2); + a.Should().Throw<Exception>(); + } + + [Fact] + public void ValueAs_Null_ShouldFail() + { + ActionResult result = new JsonResult(null); + string failureMessage = FailureMessageHelper.Format(FailureMessages.CommonNullWasSuppliedFailMessage, "Value", typeof(Object).Name); + + Action a = () => result.Should().BeJsonResult().ValueAs<Object>(); + + a.Should().Throw<Exception>() + .WithMessage(failureMessage); + } + } } \ No newline at end of file diff --git a/tests/FluentAssertions.AspNetCore.Mvc.Tests/PartialViewResultAssertions_Tests.cs b/tests/FluentAssertions.AspNetCore.Mvc.Tests/PartialViewResultAssertions_Tests.cs index 6e7881a..4765688 100644 --- a/tests/FluentAssertions.AspNetCore.Mvc.Tests/PartialViewResultAssertions_Tests.cs +++ b/tests/FluentAssertions.AspNetCore.Mvc.Tests/PartialViewResultAssertions_Tests.cs @@ -66,7 +66,7 @@ public void ModelAs_GivenWrongType_ShouldFail() public void ModelAs_Null_ShouldFail() { ActionResult result = new PartialViewResult(); - string failureMessage = FailureMessageHelper.Format(FailureMessages.ViewResultBase_NullModel, typeof(Object).Name); + string failureMessage = FailureMessageHelper.Format(FailureMessages.CommonNullWasSuppliedFailMessage, "Model", typeof(Object).Name); Action a = () => { diff --git a/tests/FluentAssertions.AspNetCore.Mvc.Tests/TestController.cs b/tests/FluentAssertions.AspNetCore.Mvc.Tests/TestController.cs index 0dce7f0..1286bf3 100644 --- a/tests/FluentAssertions.AspNetCore.Mvc.Tests/TestController.cs +++ b/tests/FluentAssertions.AspNetCore.Mvc.Tests/TestController.cs @@ -57,5 +57,10 @@ public ViewResult ViewWithTwoViewData() ViewData["key2"] = "value2"; return View(); } + + public JsonResult JsonSimpleValue() + { + return Json(data: "hello"); + } } } diff --git a/tests/FluentAssertions.AspNetCore.Mvc.Tests/ViewResultAssertions_Tests.cs b/tests/FluentAssertions.AspNetCore.Mvc.Tests/ViewResultAssertions_Tests.cs index cc28a13..3fc1c6c 100644 --- a/tests/FluentAssertions.AspNetCore.Mvc.Tests/ViewResultAssertions_Tests.cs +++ b/tests/FluentAssertions.AspNetCore.Mvc.Tests/ViewResultAssertions_Tests.cs @@ -175,7 +175,7 @@ public void ModelAs_GivenWrongType_ShouldFail() public void ModelAs_Null_ShouldFail() { ActionResult result = new ViewResult(); - string failureMessage = FailureMessageHelper.Format(FailureMessages.ViewResultBase_NullModel, typeof(Object).Name); + string failureMessage = FailureMessageHelper.Format(FailureMessages.CommonNullWasSuppliedFailMessage, "Model", typeof(Object).Name); Action a = () => result.Should().BeViewResult().ModelAs<Object>(); From 2c745ae8d59711734749c121b52c4f1cc203a2f9 Mon Sep 17 00:00:00 2001 From: Viktor Faddi <faddiv@gmail.com> Date: Mon, 17 Feb 2020 18:30:32 +0100 Subject: [PATCH 4/6] Replace WithValue with WithContentType. --- .../JsonResultAssertions.cs | 13 +++++---- .../JsonResultAssertions_Tests.cs | 27 ++++++++++++------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs b/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs index 0b97b2a..ed17c1f 100644 --- a/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs +++ b/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs @@ -43,9 +43,9 @@ public JsonResultAssertions(JsonResult subject) : base(subject) #region Public Methods /// <summary> - /// Asserts that the value is the expected value using Equals. + /// Asserts that the content type is the expected content type. /// </summary> - /// <param name="expectedValue">The expected value.</param> + /// <param name="expectedContentType">The expected content type.</param> /// <param name="reason"> /// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion /// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. @@ -53,16 +53,15 @@ public JsonResultAssertions(JsonResult subject) : base(subject) /// <param name="reasonArgs"> /// Zero or more objects to format using the placeholders in <see cref="reason" />. /// </param> - /// <returns></returns> - public JsonResultAssertions WithValue(object expectedValue, string reason = "", + public JsonResultAssertions WithContentType(string expectedContentType, string reason = "", params object[] reasonArgs) { - var actualValue = JsonResultSubject.Value; + var actualContentType = JsonResultSubject.ContentType; Execute.Assertion - .ForCondition(Equals(expectedValue, actualValue)) + .ForCondition(string.Equals(expectedContentType, actualContentType, StringComparison.OrdinalIgnoreCase)) .BecauseOf(reason, reasonArgs) - .FailWith(FailureMessages.CommonFailMessage, "JsonResult.Value", expectedValue, actualValue); + .FailWith(FailureMessages.CommonFailMessage, "JsonResult.ContentType", expectedContentType, actualContentType); return this; } diff --git a/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs b/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs index baff4c2..27339e5 100644 --- a/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs +++ b/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs @@ -8,21 +8,28 @@ namespace FluentAssertions.AspNetCore.Mvc.Tests public class JsonResultAssertions_Tests { [Fact] - public void WithValue_GivenValue_ShouldPass() + public void WithContentType_GivenValue_ShouldPass() { - ActionResult result = new JsonResult("value"); - result.Should().BeJsonResult().WithValue("value"); + ActionResult result = new JsonResult("value") + { + ContentType = "text/plain" + }; + + result.Should().BeJsonResult().WithContentType("text/plain"); } [Fact] - public void WithValue_GivenUnexpected_ShouldFail() + public void WithContentType_GivenUnexpected_ShouldFail() { - var actualValue = "xyz"; - var expectedValue = "value"; - ActionResult result = new JsonResult(actualValue); - var failureMessage = FailureMessageHelper.Format(FailureMessages.CommonFailMessage, "JsonResult.Value", expectedValue, actualValue); - - Action a = () => result.Should().BeJsonResult().WithValue(expectedValue); + var actualValue = "text/css"; + var expectedValue = "text/plain"; + ActionResult result = new JsonResult("value") + { + ContentType = actualValue + }; + var failureMessage = FailureMessageHelper.Format(FailureMessages.CommonFailMessage, "JsonResult.ContentType", expectedValue, actualValue); + + Action a = () => result.Should().BeJsonResult().WithContentType(expectedValue); a.Should().Throw<Exception>() .WithMessage(failureMessage); From 56cfb3c5a9365b8a607123b98877c46b41b04749 Mon Sep 17 00:00:00 2001 From: Viktor Faddi <faddiv@gmail.com> Date: Mon, 17 Feb 2020 18:36:15 +0100 Subject: [PATCH 5/6] Add SerializerSettings to JsonResult. --- .../JsonResultAssertions.cs | 6 ++++++ .../JsonResultAssertions_Tests.cs | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs b/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs index ed17c1f..2c43a1d 100644 --- a/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs +++ b/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs @@ -1,6 +1,7 @@ using FluentAssertions.Execution; using FluentAssertions.Primitives; using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; using System; using System.Diagnostics; @@ -27,6 +28,11 @@ public JsonResultAssertions(JsonResult subject) : base(subject) #region Public Properties + /// <summary> + /// The serializer settings of the JsonResult. + /// </summary> + public JsonSerializerSettings SerializerSettings => JsonResultSubject.SerializerSettings; + /// <summary> /// The value on the JsonResult /// </summary> diff --git a/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs b/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs index 27339e5..587278c 100644 --- a/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs +++ b/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs @@ -1,5 +1,6 @@ using FluentAssertions.Mvc.Tests.Helpers; using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; using System; using Xunit; @@ -90,5 +91,13 @@ public void ValueAs_Null_ShouldFail() .WithMessage(failureMessage); } + [Fact] + public void SerializerSettings_GivenExpectedValue_ShouldPass() + { + var expectedValue = new JsonSerializerSettings(); + var result = new JsonResult("value", expectedValue); + + result.Should().BeJsonResult().SerializerSettings.Should().BeSameAs(expectedValue); + } } } \ No newline at end of file From b7c7ec2f8575444f1e0a4a69c3e0e2abf8735b7e Mon Sep 17 00:00:00 2001 From: Viktor Faddi <faddiv@gmail.com> Date: Tue, 18 Feb 2020 21:28:43 +0100 Subject: [PATCH 6/6] Add WithStatusCode to JsonResultAssertions. --- .../JsonResultAssertions.cs | 23 ++++++++++++++ .../JsonResultAssertions_Tests.cs | 30 ++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs b/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs index 2c43a1d..25fd404 100644 --- a/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs +++ b/src/FluentAssertions.AspNetCore.Mvc/JsonResultAssertions.cs @@ -71,6 +71,29 @@ public JsonResultAssertions WithContentType(string expectedContentType, string r return this; } + /// <summary> + /// Asserts that the status code is the expected status code. + /// </summary> + /// <param name="statusCode">The expected status code.</param> + /// <param name="reason"> + /// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion + /// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. + /// </param> + /// <param name="reasonArgs"> + /// Zero or more objects to format using the placeholders in <see cref="reason" />. + /// </param> + public JsonResultAssertions WithStatusCode(int? expectedStatusCode, string reason = "", + params object[] reasonArgs) + { + var actualStatusCode = JsonResultSubject.StatusCode; + + Execute.Assertion + .ForCondition(expectedStatusCode == actualStatusCode) + .BecauseOf(reason, reasonArgs) + .FailWith(FailureMessages.CommonFailMessage, "JsonResult.StatusCode", expectedStatusCode, actualStatusCode); + return this; + } + /// <summary> /// Asserts the value is of the expected type. /// </summary> diff --git a/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs b/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs index 587278c..34dc2e3 100644 --- a/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs +++ b/tests/FluentAssertions.AspNetCore.Mvc.Tests/JsonResultAssertions_Tests.cs @@ -36,6 +36,34 @@ public void WithContentType_GivenUnexpected_ShouldFail() .WithMessage(failureMessage); } + [Fact] + public void WithStatusCode_GivenValue_ShouldPass() + { + ActionResult result = new JsonResult("value") + { + StatusCode = 200 + }; + + result.Should().BeJsonResult().WithStatusCode(200); + } + + [Fact] + public void WithStatusCode_GivenUnexpected_ShouldFail() + { + var actualStatusCode = 401; + var expectedStatusCode = 200; + ActionResult result = new JsonResult("value") + { + StatusCode = actualStatusCode + }; + var failureMessage = string.Format(FailureMessages.CommonFailMessage, "\"JsonResult.StatusCode\"", expectedStatusCode, actualStatusCode); + + Action a = () => result.Should().BeJsonResult().WithStatusCode(expectedStatusCode); + + a.Should().Throw<Exception>() + .WithMessage(failureMessage); + } + [Fact] public void Value_GivenExpectedValue_ShouldPass() { @@ -45,7 +73,7 @@ public void Value_GivenExpectedValue_ShouldPass() } [Fact] - public void Json_GivenUnexpectedValue_ShouldFail() + public void Value_GivenUnexpectedValue_ShouldFail() { var result = new TestController().JsonSimpleValue();