Skip to content

Commit d6e9498

Browse files
committed
Add CustomAssertionAttribute.
1 parent f0505c1 commit d6e9498

File tree

6 files changed

+85
-26
lines changed

6 files changed

+85
-26
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using FluentAssertions.AspNetCore.Mvc.Sample.Controllers;
2+
using Xunit;
3+
4+
namespace FluentAssertions.AspNetCore.Mvc.Sample.Tests
5+
{
6+
public class HomeController_Tests
7+
{
8+
#region Public Methods
9+
10+
[Fact]
11+
public void Index_ShouldReturnDefaultView()
12+
{
13+
var controller = new HomeController();
14+
controller.Index().Should()
15+
.BeViewResult().WithDefaultViewName();
16+
}
17+
18+
#endregion Public Methods
19+
}
20+
}

src/FluentAssertions.AspNetCore.Mvc/ActionResultAssertions.cs

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
using System.Diagnostics;
21
using FluentAssertions.Execution;
32
using FluentAssertions.Primitives;
43
using Microsoft.AspNetCore.Mvc;
4+
using System.Diagnostics;
55

66
namespace FluentAssertions.AspNetCore.Mvc
77
{
@@ -11,24 +11,25 @@ namespace FluentAssertions.AspNetCore.Mvc
1111
[DebuggerNonUserCode]
1212
public class ActionResultAssertions : ObjectAssertions
1313
{
14-
public struct Constants
15-
{
16-
public const string CommonFailMessage = "Expected ActionResult to be {0}{reason}, but found {1}";
17-
}
14+
#region Public Constructors
1815

1916
/// <summary>
2017
/// Initializes a new instance of the <see cref="T:ActionResultAssertions" /> class.
2118
/// </summary>
22-
public ActionResultAssertions (ActionResult subject) : base(subject)
19+
public ActionResultAssertions(ActionResult subject) : base(subject)
2320
{
2421
Subject = subject;
2522
}
2623

27-
public ActionResultAssertions (IActionResult subject): base(subject)
24+
public ActionResultAssertions(IActionResult subject) : base(subject)
2825
{
2926
Subject = subject;
3027
}
3128

29+
#endregion Public Constructors
30+
31+
#region Public Methods
32+
3233
/// <summary>
3334
/// Asserts that the subject is a <see cref="ContentResult"/>.
3435
/// </summary>
@@ -41,7 +42,7 @@ public ContentResultAssertions BeContentResult()
4142
/// Asserts that the subject is a <see cref="ContentResult"/>.
4243
/// </summary>
4344
/// <param name="reason">
44-
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
45+
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
4546
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
4647
/// </param>
4748
/// <param name="reasonArgs">
@@ -69,7 +70,7 @@ public EmptyResult BeEmptyResult()
6970
/// Asserts that the subject is an <see cref="EmptyResult"/>.
7071
/// </summary>
7172
/// <param name="reason">
72-
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
73+
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
7374
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
7475
/// </param>
7576
/// <param name="reasonArgs">
@@ -88,6 +89,7 @@ public EmptyResult BeEmptyResult(string reason, params object[] reasonArgs)
8889
/// <summary>
8990
/// Asserts that the subject is a <see cref="RedirectToRouteResult"/>.
9091
/// </summary>
92+
[CustomAssertion]
9193
public RedirectToRouteAssertions BeRedirectToRouteResult()
9294
{
9395
return BeRedirectToRouteResult(string.Empty, null);
@@ -97,12 +99,13 @@ public RedirectToRouteAssertions BeRedirectToRouteResult()
9799
/// Asserts that the subject is a <see cref="RedirectToRouteResult"/>.
98100
/// </summary>
99101
/// <param name="reason">
100-
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
102+
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
101103
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
102104
/// </param>
103105
/// <param name="reasonArgs">
104106
/// Zero or more objects to format using the placeholders in <see cref="reason" />.
105107
/// </param>
108+
[CustomAssertion]
106109
public RedirectToRouteAssertions BeRedirectToRouteResult(string reason, params object[] reasonArgs)
107110
{
108111
Execute.Assertion
@@ -125,7 +128,7 @@ public PartialViewResultAssertions BePartialViewResult()
125128
/// Asserts that the subject is a <see cref="PartialViewResult"/>.
126129
/// </summary>
127130
/// <param name="reason">
128-
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
131+
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
129132
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
130133
/// </param>
131134
/// <param name="reasonArgs">
@@ -153,7 +156,7 @@ public RedirectResultAssertions BeRedirectResult()
153156
/// Asserts that the subject is a <see cref="RedirectResult"/>.
154157
/// </summary>
155158
/// <param name="reason">
156-
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
159+
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
157160
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
158161
/// </param>
159162
/// <param name="reasonArgs">
@@ -181,7 +184,7 @@ public ViewResultAssertions BeViewResult()
181184
/// Asserts that the subject is a <see cref="ViewResult"/>.
182185
/// </summary>
183186
/// <param name="reason">
184-
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
187+
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
185188
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
186189
/// </param>
187190
/// <param name="reasonArgs">
@@ -191,10 +194,25 @@ public ViewResultAssertions BeViewResult(string reason, params object[] reasonAr
191194
{
192195
Execute.Assertion
193196
.BecauseOf(reason, reasonArgs)
194-
.ForCondition (Subject is ViewResult)
197+
.ForCondition(Subject is ViewResult)
195198
.FailWith(Constants.CommonFailMessage, "ViewResult", Subject.GetType().Name);
196-
197-
return new ViewResultAssertions (Subject as ViewResult);
199+
200+
return new ViewResultAssertions(Subject as ViewResult);
198201
}
202+
203+
#endregion Public Methods
204+
205+
#region Public Structs
206+
207+
public struct Constants
208+
{
209+
#region Public Fields
210+
211+
public const string CommonFailMessage = "Expected ActionResult to be {0}{reason}, but found {1}";
212+
213+
#endregion Public Fields
214+
}
215+
216+
#endregion Public Structs
199217
}
200218
}

src/FluentAssertions.AspNetCore.Mvc/FluentAssertions.AspNetCore.Mvc.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
<Version>2.0.0</Version>
2222
</PropertyGroup>
2323

24+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
25+
<OutputPath>bin\Debug\netstandard2.0\</OutputPath>
26+
</PropertyGroup>
27+
2428
<ItemGroup>
2529
<PackageReference Include="FluentAssertions" Version="5.2.0" />
2630
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.3" />

src/FluentAssertions.AspNetCore.Mvc/RedirectToRouteAssertions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public RedirectToRouteAssertions WithRouteName(string expectedRouteName, string
8787
/// <param name="reasonArgs">
8888
/// Zero or more objects to format using the placeholders in <see cref="reason" />.
8989
/// </param>
90+
[CustomAssertion]
9091
public RedirectToRouteAssertions WithRouteValue(string key, object expectedValue, string reason = "", params object[] reasonArgs)
9192
{
9293
Subject.RouteValues.Should().Contain(new KeyValuePair<string, object>(key, expectedValue), reason, reasonArgs);

src/FluentAssertions.AspNetCore.Mvc/ViewResultAssertions.cs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
using System;
2-
using System.Diagnostics;
3-
using FluentAssertions.Execution;
1+
using FluentAssertions.Execution;
42
using FluentAssertions.Primitives;
53
using Microsoft.AspNetCore.Mvc;
4+
using System;
5+
using System.Diagnostics;
66

77
namespace FluentAssertions.AspNetCore.Mvc
88
{
@@ -12,6 +12,8 @@ namespace FluentAssertions.AspNetCore.Mvc
1212
[DebuggerNonUserCode]
1313
public class ViewResultAssertions : ObjectAssertions
1414
{
15+
#region Public Constructors
16+
1517
/// <summary>
1618
/// Initializes a new instance of the <see cref="T:ViewResultAssertions" /> class.
1719
/// </summary>
@@ -20,13 +22,25 @@ public ViewResultAssertions(ViewResult subject) : base(subject)
2022
{
2123
}
2224

23-
private ViewResult ViewResultSubject => (ViewResult) Subject;
25+
#endregion Public Constructors
26+
27+
#region Public Properties
2428

2529
/// <summary>
2630
/// The model.
2731
/// </summary>
2832
public object Model => ViewResultSubject.Model;
2933

34+
#endregion Public Properties
35+
36+
#region Private Properties
37+
38+
private ViewResult ViewResultSubject => (ViewResult)Subject;
39+
40+
#endregion Private Properties
41+
42+
#region Public Methods
43+
3044
/// <summary>
3145
/// Asserts that the view name is the expected view name.
3246
/// </summary>
@@ -125,7 +139,7 @@ public TModel ModelAs<TModel>()
125139
.ForCondition(model is TModel)
126140
.FailWith("Expected Model to be of type '{0}' but was '{1}'", typeof(TModel).Name, model.GetType().Name);
127141

128-
return (TModel) model;
142+
return (TModel)model;
129143
}
130144

131145
/// <summary>
@@ -143,11 +157,13 @@ public ViewResultAssertions WithDefaultViewName(string reason = "", params objec
143157
var viewName = ViewResultSubject.ViewName;
144158

145159
Execute.Assertion
146-
.ForCondition(viewName == string.Empty)
160+
.ForCondition(string.IsNullOrEmpty(viewName))
147161
.BecauseOf(reason, reasonArgs)
148162
.FailWith(FailureMessages.ViewResultBase_WithDefaultViewName, viewName);
149163

150164
return this;
151165
}
166+
167+
#endregion Public Methods
152168
}
153169
}

tests/FluentAssertions.AspNetCore.Mvc.Tests/RedirectToRoute_Tests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public void WithRouteValue_GivenUnexpected_ShouldFail()
7575
.WithRouteValue("Id", "11");
7676

7777
a.Should().Throw<Exception>()
78-
.WithMessage("Expected Subject.RouteValues to contain value \"11\" at key \"Id\", but found \"22\".");
78+
.WithMessage("Expected result to contain value \"11\" at key \"Id\", but found \"22\".");
7979
}
8080

8181
[Fact]
@@ -103,7 +103,7 @@ public void WithController_GivenUnexpected_ShouldFail()
103103
.BeRedirectToRouteResult()
104104
.WithController("xyz");
105105
a.Should().Throw<Exception>()
106-
.WithMessage("Expected Subject.RouteValues to contain value \"xyz\" at key \"Controller\", but found \"home\".");
106+
.WithMessage("Expected dictionary to contain value \"xyz\" at key \"Controller\", but found \"home\".");
107107
}
108108

109109
[Fact]
@@ -132,7 +132,7 @@ public void WithAction_GivenUnexpected_ShouldFail()
132132
.WithAction("xyz");
133133

134134
a.Should().Throw<Exception>()
135-
.WithMessage("Expected Subject.RouteValues to contain value \"xyz\" at key \"Action\", but found \"index\".");
135+
.WithMessage("Expected dictionary to contain value \"xyz\" at key \"Action\", but found \"index\".");
136136
}
137137

138138
[Fact]
@@ -161,7 +161,7 @@ public void WithArea_GivenUnexpected_ShouldFail()
161161
.WithArea("xyz");
162162

163163
a.Should().Throw<Exception>()
164-
.WithMessage("Expected Subject.RouteValues to contain value \"xyz\" at key \"Area\", but found \"accounts\".");
164+
.WithMessage("Expected dictionary to contain value \"xyz\" at key \"Area\", but found \"accounts\".");
165165
}
166166

167167
#endregion Public Methods

0 commit comments

Comments
 (0)