Skip to content

Commit f829415

Browse files
committed
Implemented .ShouldReturn().ActionResult(result => result.Ok()) assertion chain (#359)
1 parent 7098c9b commit f829415

7 files changed

Lines changed: 91 additions & 26 deletions

File tree

src/MyTested.AspNetCore.Mvc.Controllers/Builders/Actions/AndActionResultTestBuilder.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@ public class AndActionResultTestBuilder<TActionResult> : ShouldHaveTestBuilder<T
1717
/// </summary>
1818
/// <param name="testContext"><see cref="ControllerTestContext"/> containing data about the currently executed assertion chain.</param>
1919
public AndActionResultTestBuilder(ControllerTestContext testContext)
20-
: base(testContext)
21-
{
22-
TestHelper.ExecuteTestCleanup();
23-
}
20+
: base(testContext)
21+
=> TestHelper.ExecuteTestCleanup();
2422

2523
/// <inheritdoc />
2624
public IActionResultTestBuilder<TActionResult> AndAlso()

src/MyTested.AspNetCore.Mvc.Controllers/Builders/Actions/ShouldHave/ShouldHaveActionAttributes.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,8 @@ public IAndActionResultTestBuilder<TActionResult> ActionAttributes(Action<IActio
4747
return this.Builder;
4848
}
4949

50-
private void ThrowNewAttributeAssertionException(string expectedValue, string actualValue)
51-
{
52-
throw new AttributeAssertionException(
50+
private void ThrowNewAttributeAssertionException(string expectedValue, string actualValue)
51+
=> throw new AttributeAssertionException(
5352
$"{this.TestContext.ExceptionMessagePrefix} action to {expectedValue}, but {actualValue}.");
54-
}
5553
}
5654
}

src/MyTested.AspNetCore.Mvc.Controllers/Builders/Actions/ShouldHave/ShouldHaveTestBuilder.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,16 @@ public partial class ShouldHaveTestBuilder<TActionResult>
2020
/// </summary>
2121
/// <param name="testContext"><see cref="ControllerTestContext"/> containing data about the currently executed assertion chain.</param>
2222
public ShouldHaveTestBuilder(ControllerTestContext testContext)
23-
: base(testContext)
24-
{
25-
this.TestContext = testContext;
26-
}
27-
23+
: base(testContext)
24+
=> this.TestContext = testContext;
25+
2826
/// <summary>
2927
/// Gets the currently used <see cref="ControllerTestContext"/>.
3028
/// </summary>
3129
/// <value>Result of type <see cref="ControllerTestContext"/>.</value>
3230
public new ControllerTestContext TestContext
3331
{
34-
get
35-
{
36-
return this.testContext;
37-
}
32+
get => this.testContext;
3833

3934
private set
4035
{

src/MyTested.AspNetCore.Mvc.Controllers/Builders/Actions/ShouldReturn/ShouldReturnActionResultTestBuilder.cs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
namespace MyTested.AspNetCore.Mvc.Builders.Actions.ShouldReturn
22
{
3+
using System;
34
using And;
45
using Contracts.Actions;
56
using Contracts.And;
@@ -14,6 +15,9 @@
1415
public class ShouldReturnActionResultTestBuilder<TActionResult>
1516
: ShouldReturnTestBuilder<TActionResult>, IShouldReturnActionResultTestBuilder<TActionResult>
1617
{
18+
private static readonly Type ActionResultType = typeof(IActionResult);
19+
private static readonly Type GenericActionResultType = typeof(ActionResult<>);
20+
1721
/// <summary>
1822
/// Initializes a new instance of the <see cref="ShouldReturnActionResultTestBuilder{TActionResult}"/> class.
1923
/// </summary>
@@ -24,14 +28,27 @@ public ShouldReturnActionResultTestBuilder(ControllerTestContext testContext)
2428
}
2529

2630
/// <inheritdoc />
27-
public new IAndTestBuilder ActionResult()
31+
IAndTestBuilder IShouldReturnActionResultTestBuilder<TActionResult>.ActionResult()
2832
{
29-
InvocationResultValidator.ValidateInvocationResultTypes(
30-
this.TestContext,
31-
canBeAssignable: true,
32-
typesOfExpectedReturnValue: new [] { typeof(IActionResult), typeof(ActionResult<>) });
33+
this.ValidateActionResults();
3334

3435
return new AndTestBuilder(this.TestContext);
3536
}
37+
38+
/// <inheritdoc />
39+
IAndTestBuilder IShouldReturnActionResultTestBuilder<TActionResult>.ActionResult(Action<IShouldReturnTestBuilder<TActionResult>> actionResultTestBuilder)
40+
{
41+
this.ValidateActionResults();
42+
43+
actionResultTestBuilder?.Invoke(this);
44+
45+
return new AndTestBuilder(this.TestContext);
46+
}
47+
48+
private void ValidateActionResults()
49+
=> InvocationResultValidator.ValidateInvocationResultTypes(
50+
this.TestContext,
51+
canBeAssignable: true,
52+
typesOfExpectedReturnValue: new[] { ActionResultType, GenericActionResultType });
3653
}
3754
}

src/MyTested.AspNetCore.Mvc.Controllers/Builders/Contracts/Actions/IShouldReturnActionResultTestBuilder.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ public interface IShouldReturnActionResultTestBuilder<TActionResult>
1818
/// <returns>Test builder of <see cref="IAndTestBuilder"/> type.</returns>
1919
IAndTestBuilder ActionResult();
2020

21-
//// IActionResult, ActionResult or ActionResult<T> with options to specify the result - Ok() for example
22-
//IAndTestBuilder ActionResult(Action<IShouldReturnTestBuilder<TActionResult>> actionResultTestBuilder);
21+
/// Tests whether the action result is <see cref="Microsoft.AspNetCore.Mvc.IActionResult"/>,
22+
/// <see cref="Microsoft.AspNetCore.Mvc.ActionResult"/> or
23+
/// <see cref="Microsoft.AspNetCore.Mvc.ActionResult{TResult}"/>.
24+
/// <param name="actionResultTestBuilder">Test builder which asserts the actual action result.</param>
25+
/// <returns>Test builder of <see cref="IAndTestBuilder"/> type.</returns>
26+
IAndTestBuilder ActionResult(Action<IShouldReturnTestBuilder<TActionResult>> actionResultTestBuilder);
2327

2428
//// ActionResult<TResult>, consider OkResult for example to be valid too?
2529
//IAndTestBuilder ActionResult<TResult>();

test/MyTested.AspNetCore.Mvc.Controllers.Test/BuildersTests/ActionsTests/ShouldReturnTests/ShouldReturnActionResultTests.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Exceptions;
44
using Setups;
55
using Setups.Controllers;
6+
using Setups.Models;
67
using Xunit;
78

89
public class ShouldReturnActionResultTests
@@ -51,5 +52,57 @@ public void ShouldReturnActionResultShouldThrowExceptionWhenWhenResultIsNotActio
5152
},
5253
"When calling AnonymousResult action in MvcController expected result to be IActionResult or ActionResult<TValue>, but instead received AnonymousType<Int32, String, AnonymousType<Boolean>>.");
5354
}
55+
56+
[Fact]
57+
public void ShouldReturnActionResultWithDetailsShouldNotThrowExceptionWhenResultIsIActionResultInterface()
58+
{
59+
MyController<MvcController>
60+
.Instance()
61+
.Calling(c => c.ActionResultInterface())
62+
.ShouldReturn()
63+
.ActionResult(result => result
64+
.Ok(okResult => okResult
65+
.Passing(ok => ok.Value?.GetType() == typeof(ResponseModel))));
66+
}
67+
68+
[Fact]
69+
public void ShouldReturnActionResultWithDetailsShouldNotThrowExceptionWhenResultIsIActionResultBaseClass()
70+
{
71+
MyController<MvcController>
72+
.Instance()
73+
.Calling(c => c.ActionResultBaseClass())
74+
.ShouldReturn()
75+
.ActionResult(result => result
76+
.Ok(okResult => okResult
77+
.Passing(ok => ok.Value?.GetType() == typeof(ResponseModel))));
78+
}
79+
80+
[Fact]
81+
public void ShouldReturnActionResultWithDetailsShouldNotThrowExceptionWhenResultIsActionResultOfT()
82+
{
83+
MyController<MvcController>
84+
.Instance()
85+
.Calling(c => c.ActionResultOfT(int.MaxValue))
86+
.ShouldReturn()
87+
.ActionResult(result => result
88+
.Ok(okResult => okResult
89+
.Passing(ok => ok.Value?.GetType() == typeof(ResponseModel))));
90+
}
91+
92+
[Fact]
93+
public void ShouldReturnActionResultWithDetailsShouldThrowExceptionWhenWhenResultIsNotActionResult()
94+
{
95+
Test.AssertException<InvocationResultAssertionException>(
96+
() =>
97+
{
98+
MyController<MvcController>
99+
.Instance()
100+
.Calling(c => c.BadRequestAction())
101+
.ShouldReturn()
102+
.ActionResult(result => result
103+
.Ok());
104+
},
105+
"When calling BadRequestAction action in MvcController expected result to be OkResult, but instead received BadRequestResult.");
106+
}
54107
}
55108
}

test/MyTested.AspNetCore.Mvc.Test.Setups/Controllers/MvcController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,12 +1249,12 @@ public IActionResult WithService(IHttpContextAccessor httpContextAccessor)
12491249

12501250
public IActionResult ActionResultInterface()
12511251
{
1252-
return this.Ok();
1252+
return this.Ok(this.ResponseModel.First());
12531253
}
12541254

12551255
public ActionResult ActionResultBaseClass()
12561256
{
1257-
return this.Ok();
1257+
return this.Ok(this.ResponseModel.First());
12581258
}
12591259

12601260
public ActionResult<ResponseModel> ActionResultOfT(int id)

0 commit comments

Comments
 (0)