Skip to content

Commit 4ab62e1

Browse files
committed
Add Basic ObjectAssertions.
1 parent d1f4e52 commit 4ab62e1

File tree

5 files changed

+190
-0
lines changed

5 files changed

+190
-0
lines changed

src/FluentAssertions.AspNetCore.Mvc/ActionResultAssertions.cs

+21
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,27 @@ public StatusCodeResultAssertions BeStatusCodeResult(string reason = "", params
325325
return new StatusCodeResultAssertions(Subject as StatusCodeResult);
326326
}
327327

328+
/// <summary>
329+
/// Asserts that the subject is a <see cref="ObjectResult"/>.
330+
/// </summary>
331+
/// <param name="reason">
332+
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
333+
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
334+
/// </param>
335+
/// <param name="reasonArgs">
336+
/// Zero or more objects to format using the placeholders in <paramref name="reason"/>.
337+
/// </param>
338+
[CustomAssertion]
339+
public ObjectResultAssertions BeObjectResult(string reason = "", params object[] reasonArgs)
340+
{
341+
Execute.Assertion
342+
.BecauseOf(reason, reasonArgs)
343+
.ForCondition(Subject is ObjectResult)
344+
.FailWith(FailureMessages.CommonTypeFailMessage, typeof(ObjectResult), Subject.GetType());
345+
346+
return new ObjectResultAssertions(Subject as ObjectResult);
347+
}
348+
328349
/// <summary>
329350
/// Asserts that the subject is an <see cref="OkResult"/>.
330351
/// </summary>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using System.Diagnostics;
3+
4+
namespace FluentAssertions.AspNetCore.Mvc
5+
{
6+
/// <summary>
7+
/// Contains a number of methods to assert that a <see cref="ObjectResult"/> is in the expected state.
8+
/// </summary>
9+
[DebuggerNonUserCode]
10+
public class ObjectResultAssertions : ObjectResultAssertionsBase<ObjectResult, ObjectResultAssertions>
11+
{
12+
#region Public Constructors
13+
/// <summary>
14+
/// Initializes a new instance of the <see cref="ObjectResultAssertions" /> class.
15+
/// </summary>
16+
/// <param name="subject">The object to test assertion on</param>
17+
public ObjectResultAssertions(ObjectResult subject)
18+
: base(subject)
19+
{
20+
21+
}
22+
#endregion
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using FluentAssertions.Execution;
2+
using FluentAssertions.Primitives;
3+
using Microsoft.AspNetCore.Mvc;
4+
using System.Diagnostics;
5+
6+
namespace FluentAssertions.AspNetCore.Mvc
7+
{
8+
/// <summary>
9+
/// Base class for <see cref="ObjectResultAssertions"/>.
10+
/// </summary>
11+
[DebuggerNonUserCode]
12+
public class ObjectResultAssertionsBase<TObjectResult, TObjectResultAssertion> : ObjectAssertions
13+
where TObjectResult : ObjectResult
14+
where TObjectResultAssertion : ObjectResultAssertionsBase<TObjectResult, TObjectResultAssertion>
15+
{
16+
#region Public Constructors
17+
/// <summary>
18+
/// Initializes a new instance of the <see cref="ObjectResultAssertions" /> class.
19+
/// </summary>
20+
/// <param name="subject">The object to test assertion on</param>
21+
public ObjectResultAssertionsBase(TObjectResult subject)
22+
: base(subject)
23+
{
24+
25+
}
26+
#endregion
27+
28+
#region Public Properties
29+
30+
/// <summary>
31+
/// The value on the ObjectResult
32+
/// </summary>
33+
public object Value => ObjectResultSubject.Value;
34+
35+
#endregion
36+
37+
#region Protected Properties
38+
39+
/// <inheritdoc />
40+
protected override string Identifier => typeof(TObjectResult).Name;
41+
/// <summary>
42+
/// The <see cref="ReferenceTypeAssertions{TSubject, TAssertions}.Subject"/> casted to the correct type.
43+
/// </summary>
44+
protected TObjectResult ObjectResultSubject => (TObjectResult)Subject;
45+
46+
#endregion
47+
48+
#region Public Methods
49+
/// <summary>
50+
/// Asserts the value is of the expected type.
51+
/// </summary>
52+
/// <typeparam name="TValue">The expected type.</typeparam>
53+
/// <returns>The typed value.</returns>
54+
public TValue ValueAs<TValue>()
55+
{
56+
var value = ObjectResultSubject.Value;
57+
58+
if (value == null)
59+
Execute.Assertion
60+
.WithDefaultIdentifier($"{Identifier}.Value")
61+
.FailWith(FailureMessages.CommonNullWasSuppliedFailMessage, typeof(TValue));
62+
63+
Execute.Assertion
64+
.ForCondition(value is TValue)
65+
.WithDefaultIdentifier($"{Identifier}.Value")
66+
.FailWith(FailureMessages.CommonTypeFailMessage, typeof(TValue), value.GetType());
67+
68+
return (TValue)value;
69+
}
70+
#endregion
71+
72+
}
73+
}

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

+20
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,26 @@ public void BeStatusCodeResult_GivenNotStatusCodeResult_ShouldFail()
282282
.WithMessage(failureMessage);
283283
}
284284

285+
[Fact]
286+
public void BeObjectResult_GivenObjectResult_ShouldPass()
287+
{
288+
ActionResult result = new ObjectResult("TestValue");
289+
290+
result.Should().BeObjectResult();
291+
}
292+
293+
[Fact]
294+
public void BeObjectResult_GivenNotObjectResult_ShouldFail()
295+
{
296+
ActionResult result = new ViewResult();
297+
var failureMessage = FailureMessageHelper.ExpectedContextTypeXButFoundY("result", typeof(ObjectResult), typeof(ViewResult));
298+
299+
Action a = () => result.Should().BeObjectResult(Reason, ReasonArgs);
300+
301+
a.Should().Throw<Exception>()
302+
.WithMessage(failureMessage);
303+
}
304+
285305
[Fact]
286306
public void BeOkResult_GivenOk_ShouldPass()
287307
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System;
2+
using FluentAssertions.Mvc.Tests.Helpers;
3+
using Microsoft.AspNetCore.Mvc;
4+
using Xunit;
5+
6+
namespace FluentAssertions.AspNetCore.Mvc.Tests
7+
{
8+
public class ObjectResultAssertions_Tests
9+
{
10+
private const string TestValue = "testValue";
11+
[Fact]
12+
public void Value_GivenObjectResult_ShouldHaveTheSameValue()
13+
{
14+
var result = new ObjectResult(TestValue);
15+
result.Should().BeObjectResult().Value.Should().BeSameAs(TestValue);
16+
}
17+
18+
[Fact]
19+
public void ValueAs_GivenObjectResult_ShouldHaveTheSameValue()
20+
{
21+
var result = new ObjectResult(TestValue);
22+
23+
result.Should().BeObjectResult().ValueAs<string>().Should().BeSameAs(TestValue);
24+
}
25+
26+
[Fact]
27+
public void ValueAs_GivenWrongType_ShouldFail()
28+
{
29+
var result = new ObjectResult(TestValue);
30+
string failureMessage = FailureMessageHelper.ExpectedContextTypeXButFoundY(
31+
"ObjectResult.Value", typeof(int), typeof(string));
32+
33+
Action a = () => result.Should().BeObjectResult().ValueAs<int>().Should().Be(2);
34+
35+
a.Should().Throw<Exception>()
36+
.WithMessage(failureMessage);
37+
}
38+
39+
[Fact]
40+
public void ValueAs_Null_ShouldFail()
41+
{
42+
ActionResult result = new ObjectResult(null);
43+
string failureMessage = FailureMessageHelper.ExpectedContextTypeXButFoundNull(
44+
"ObjectResult.Value", typeof(object));
45+
46+
Action a = () => result.Should().BeObjectResult().ValueAs<object>();
47+
48+
a.Should().Throw<Exception>()
49+
.WithMessage(failureMessage);
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)