Skip to content

Commit 823d7bc

Browse files
committed
Add request unit tests
1 parent 2e8dee2 commit 823d7bc

File tree

4 files changed

+250
-3
lines changed

4 files changed

+250
-3
lines changed

src/Abstractions/TaskActivity.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,28 @@ public abstract class TaskActivity<TInput> : ITaskActivity
111111
/// <returns>The output of the activity as a task.</returns>
112112
public abstract Task RunAsync(TaskActivityContext context, TInput input);
113113
}
114+
115+
/// <inheritdoc cref="TaskActivity{Unit, Unit}" />
116+
public abstract class TaskActivity : ITaskActivity
117+
{
118+
/// <inheritdoc/>
119+
Type ITaskActivity.InputType => typeof(Unit);
120+
121+
/// <inheritdoc/>
122+
Type ITaskActivity.OutputType => typeof(Unit);
123+
124+
/// <inheritdoc/>
125+
async Task<object?> ITaskActivity.RunAsync(TaskActivityContext context, object? input)
126+
{
127+
Check.NotNull(context, nameof(context));
128+
await this.RunAsync(context);
129+
return Unit.Value;
130+
}
131+
132+
/// <summary>
133+
/// Override to implement async (non-blocking) task activity logic.
134+
/// </summary>
135+
/// <param name="context">Provides access to additional context for the current activity execution.</param>
136+
/// <returns>The output of the activity as a task.</returns>
137+
public abstract Task RunAsync(TaskActivityContext context);
138+
}

src/Abstractions/TaskOrchestrator.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
using System.Diagnostics.CodeAnalysis;
5-
using Microsoft.Extensions.Logging;
6-
74
namespace Microsoft.DurableTask;
85

96
/// <summary>
@@ -164,3 +161,28 @@ public abstract class TaskOrchestrator<TInput> : ITaskOrchestrator
164161
/// <returns>A task that completes when the orchestration is complete.</returns>
165162
public abstract Task RunAsync(TaskOrchestrationContext context, TInput input);
166163
}
164+
165+
/// <inheritdoc cref="TaskOrchestrator{Unit, Unit}" />.
166+
public abstract class TaskOrchestrator : ITaskOrchestrator
167+
{
168+
/// <inheritdoc/>
169+
public Type InputType => typeof(Unit);
170+
171+
/// <inheritdoc/>
172+
public Type OutputType => typeof(Unit);
173+
174+
/// <inheritdoc/>
175+
async Task<object?> ITaskOrchestrator.RunAsync(TaskOrchestrationContext context, object? input)
176+
{
177+
Check.NotNull(context, nameof(context));
178+
await this.RunAsync(context);
179+
return Unit.Value;
180+
}
181+
182+
/// <summary>
183+
/// Override to implement task orchestrator logic.
184+
/// </summary>
185+
/// <param name="context">The task orchestrator's context.</param>
186+
/// <returns>A task that completes when the orchestration is complete.</returns>
187+
public abstract Task RunAsync(TaskOrchestrationContext context);
188+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
5+
namespace Microsoft.DurableTask.Tests;
6+
7+
public class ActivityRequestTests
8+
{
9+
[Theory]
10+
[InlineData(null)]
11+
[InlineData(10)]
12+
public void Create_Success(int? input)
13+
{
14+
TaskName name = "Test";
15+
IActivityRequest request = ActivityRequest.Create(name, input);
16+
17+
request.GetInput().Should().Be(input);
18+
request.GetTaskName().Should().Be(name);
19+
}
20+
21+
[Theory]
22+
[InlineData(null)]
23+
[InlineData("input")]
24+
public void Create_OfT_Success(string input)
25+
{
26+
TaskName name = "Test";
27+
IActivityRequest<int> request = ActivityRequest.Create<int>(name, input);
28+
29+
request.GetInput().Should().Be(input);
30+
request.GetTaskName().Should().Be(name);
31+
}
32+
33+
[Theory]
34+
[InlineData(null)]
35+
[InlineData("input")]
36+
public async Task RunRequest_Success(string input)
37+
{
38+
TaskName name = "Test";
39+
IActivityRequest request = ActivityRequest.Create(name, input);
40+
Mock<TaskOrchestrationContext> context = new(MockBehavior.Strict);
41+
context.Setup(m => m.CallActivityAsync(name, input, null)).Returns(Task.CompletedTask);
42+
43+
await context.Object.RunAsync(request);
44+
45+
context.Verify(m => m.CallActivityAsync(name, input, null), Times.Once);
46+
}
47+
48+
[Theory]
49+
[InlineData(null)]
50+
[InlineData("input")]
51+
public async Task RunRequest_OfT_Success(string input)
52+
{
53+
TaskName name = "Test";
54+
IActivityRequest<int> request = ActivityRequest.Create<int>(name, input);
55+
Mock<TaskOrchestrationContext> context = new(MockBehavior.Strict);
56+
context.Setup(m => m.CallActivityAsync<int>(name, input, null)).Returns(Task.FromResult(0));
57+
58+
await context.Object.RunAsync(request);
59+
60+
context.Verify(m => m.CallActivityAsync<int>(name, input, null), Times.Once);
61+
}
62+
63+
[Fact]
64+
public async Task RunRequest2_Success()
65+
{
66+
IActivityRequest request = new DirectRequest();
67+
Mock<TaskOrchestrationContext> context = new(MockBehavior.Strict);
68+
context.Setup(m => m.CallActivityAsync(DirectRequest.Name, request, null)).Returns(Task.CompletedTask);
69+
70+
await context.Object.RunAsync(request);
71+
72+
context.Verify(m => m.CallActivityAsync(DirectRequest.Name, request, null), Times.Once);
73+
}
74+
75+
[Fact]
76+
public async Task RunRequest2_OfT_Success()
77+
{
78+
TaskName name = "Test";
79+
IActivityRequest<int> request = new DirectRequest2();
80+
Mock<TaskOrchestrationContext> context = new(MockBehavior.Strict);
81+
context.Setup(m => m.CallActivityAsync<int>(DirectRequest.Name, request, null))
82+
.Returns(Task.FromResult(0));
83+
84+
await context.Object.RunAsync(request);
85+
86+
context.Verify(m => m.CallActivityAsync<int>(DirectRequest.Name, request, null), Times.Once);
87+
}
88+
89+
class DirectRequest : IActivityRequest
90+
{
91+
public static readonly TaskName Name = "DirectRequest";
92+
93+
public TaskName GetTaskName() => Name;
94+
}
95+
96+
class DirectRequest2 : IActivityRequest<int>
97+
{
98+
public TaskName GetTaskName() => DirectRequest.Name;
99+
}
100+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
5+
namespace Microsoft.DurableTask.Tests;
6+
7+
public class OrchestrationRequestTests
8+
{
9+
[Theory]
10+
[InlineData(null)]
11+
[InlineData(10)]
12+
public void Create_Success(int? input)
13+
{
14+
TaskName name = "Test";
15+
IOrchestrationRequest request = OrchestrationRequest.Create(name, input);
16+
17+
request.GetInput().Should().Be(input);
18+
request.GetTaskName().Should().Be(name);
19+
}
20+
21+
[Theory]
22+
[InlineData(null)]
23+
[InlineData("input")]
24+
public void Create_OfT_Success(string input)
25+
{
26+
TaskName name = "Test";
27+
IOrchestrationRequest<int> request = OrchestrationRequest.Create<int>(name, input);
28+
29+
request.GetInput().Should().Be(input);
30+
request.GetTaskName().Should().Be(name);
31+
}
32+
33+
[Theory]
34+
[InlineData(null)]
35+
[InlineData("input")]
36+
public async Task RunRequest_Success(string input)
37+
{
38+
TaskName name = "Test";
39+
IOrchestrationRequest request = OrchestrationRequest.Create(name, input);
40+
Mock<TaskOrchestrationContext> context = new(MockBehavior.Strict);
41+
context.Setup(m => m.CallSubOrchestratorAsync(name, input, null)).Returns(Task.CompletedTask);
42+
43+
await context.Object.RunAsync(request);
44+
45+
context.Verify(m => m.CallSubOrchestratorAsync(name, input, null), Times.Once);
46+
}
47+
48+
[Theory]
49+
[InlineData(null)]
50+
[InlineData("input")]
51+
public async Task RunRequest_OfT_Success(string input)
52+
{
53+
TaskName name = "Test";
54+
IOrchestrationRequest<int> request = OrchestrationRequest.Create<int>(name, input);
55+
Mock<TaskOrchestrationContext> context = new(MockBehavior.Strict);
56+
context.Setup(m => m.CallSubOrchestratorAsync<int>(name, input, null)).Returns(Task.FromResult(0));
57+
58+
await context.Object.RunAsync(request);
59+
60+
context.Verify(m => m.CallSubOrchestratorAsync<int>(name, input, null), Times.Once);
61+
}
62+
63+
[Fact]
64+
public async Task RunRequest2_Success()
65+
{
66+
IOrchestrationRequest request = new DirectRequest();
67+
Mock<TaskOrchestrationContext> context = new(MockBehavior.Strict);
68+
context.Setup(m => m.CallSubOrchestratorAsync(DirectRequest.Name, request, null)).Returns(Task.CompletedTask);
69+
70+
await context.Object.RunAsync(request);
71+
72+
context.Verify(m => m.CallSubOrchestratorAsync(DirectRequest.Name, request, null), Times.Once);
73+
}
74+
75+
[Fact]
76+
public async Task RunRequest2_OfT_Success()
77+
{
78+
TaskName name = "Test";
79+
IOrchestrationRequest<int> request = new DirectRequest2();
80+
Mock<TaskOrchestrationContext> context = new(MockBehavior.Strict);
81+
context.Setup(m => m.CallSubOrchestratorAsync<int>(DirectRequest.Name, request, null))
82+
.Returns(Task.FromResult(0));
83+
84+
await context.Object.RunAsync(request);
85+
86+
context.Verify(m => m.CallSubOrchestratorAsync<int>(DirectRequest.Name, request, null), Times.Once);
87+
}
88+
89+
class DirectRequest : IOrchestrationRequest
90+
{
91+
public static readonly TaskName Name = "DirectRequest";
92+
93+
public TaskName GetTaskName() => Name;
94+
}
95+
96+
class DirectRequest2 : IOrchestrationRequest<int>
97+
{
98+
public TaskName GetTaskName() => DirectRequest.Name;
99+
}
100+
}

0 commit comments

Comments
 (0)