Skip to content

Commit fc74da8

Browse files
perditavojoCopilot
andcommitted
test: fix xUnit1051/xUnit1031 analyzer warnings
- Pass TestContext.Current.CancellationToken to all Task.Delay / Task.Run calls - Replace blocking tcs.Task.Result with await (xUnit1031) - Suppress xUnit1051 on intentionally-cancelled cts.Token in Task.Run Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 3d4d19b commit fc74da8

2 files changed

Lines changed: 23 additions & 13 deletions

File tree

tests/InputBox.Tests/AnnouncementServiceTests.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public async Task Enqueue_EmptyString_DoesNotInvokeDelegate()
3939
_svc.Enqueue(string.Empty);
4040

4141
// 等待足夠時間讓背景工作有機會執行
42-
await Task.Delay(600);
42+
await Task.Delay(600, TestContext.Current.CancellationToken);
4343

4444
Assert.False(invoked);
4545
}
@@ -61,7 +61,7 @@ public async Task Enqueue_AfterDispose_DoesNotInvokeDelegate()
6161
_svc.Dispose();
6262
_svc.Enqueue("hello after dispose");
6363

64-
await Task.Delay(600);
64+
await Task.Delay(600, TestContext.Current.CancellationToken);
6565

6666
Assert.False(invoked);
6767
}
@@ -83,9 +83,10 @@ public async Task Enqueue_ValidMessage_EventuallyInvokesDelegate()
8383
_svc.Enqueue("測試廣播");
8484

8585
// 等待最多 2 秒讓背景工作完成(含 ducking 延遲與 jitter)
86-
string? received = await Task.WhenAny(tcs.Task, Task.Delay(2000)) == tcs.Task
87-
? tcs.Task.Result
88-
: null;
86+
Task<string> completionTask = tcs.Task;
87+
Task timeoutTask = Task.Delay(2000, TestContext.Current.CancellationToken);
88+
Task finished = await Task.WhenAny(completionTask, timeoutTask);
89+
string? received = finished == completionTask ? await completionTask : null;
8990

9091
Assert.Equal("測試廣播", received);
9192
}

tests/InputBox.Tests/TaskExtensionsTests.cs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public async Task SafeFireAndForget_SuccessfulTask_DoesNotInvokeOnException()
7777
Task.CompletedTask.SafeFireAndForget(
7878
onException: _ => exceptionInvoked = true);
7979

80-
await Task.Delay(100);
80+
await Task.Delay(100, TestContext.Current.CancellationToken);
8181

8282
Assert.False(exceptionInvoked);
8383
}
@@ -92,14 +92,17 @@ public async Task SafeFireAndForget_CancelledTask_DoesNotInvokeOnException()
9292
using var cts = new CancellationTokenSource();
9393
cts.Cancel();
9494

95+
// 此處 cts.Token 是刻意已取消的 token,pragma 抑制 xUnit1051 以保持測試語意清晰
96+
#pragma warning disable xUnit1051
9597
Task cancelledTask = Task.Run(
9698
() => cts.Token.ThrowIfCancellationRequested(),
9799
cts.Token);
100+
#pragma warning restore xUnit1051
98101

99102
cancelledTask.SafeFireAndForget(
100103
onException: _ => exceptionInvoked = true);
101104

102-
await Task.Delay(150);
105+
await Task.Delay(150, TestContext.Current.CancellationToken);
103106

104107
Assert.False(exceptionInvoked);
105108
}
@@ -112,13 +115,15 @@ public async Task SafeFireAndForget_FaultedTask_InvokesOnException()
112115
{
113116
Exception? captured = null;
114117

115-
Task faultedTask = Task.Run(() => throw new InvalidOperationException("test-error"));
118+
Task faultedTask = Task.Run(
119+
() => throw new InvalidOperationException("test-error"),
120+
TestContext.Current.CancellationToken);
116121

117122
faultedTask.SafeFireAndForget(
118123
onException: ex => captured = ex);
119124

120125
// 等待背景任務完成處理
121-
await Task.Delay(300);
126+
await Task.Delay(300, TestContext.Current.CancellationToken);
122127

123128
Assert.NotNull(captured);
124129
Assert.IsType<InvalidOperationException>(captured);
@@ -133,12 +138,14 @@ public async Task SafeFireAndForget_WithAnnounceAction_InvokesWithMessage()
133138
{
134139
string? announced = null;
135140

136-
Task faultedTask = Task.Run(() => throw new Exception("announce-me"));
141+
Task faultedTask = Task.Run(
142+
() => throw new Exception("announce-me"),
143+
TestContext.Current.CancellationToken);
137144

138145
faultedTask.SafeFireAndForget(
139146
announceAction: msg => announced = msg);
140147

141-
await Task.Delay(300);
148+
await Task.Delay(300, TestContext.Current.CancellationToken);
142149

143150
Assert.NotNull(announced);
144151
Assert.Contains("announce-me", announced);
@@ -152,13 +159,15 @@ public async Task SafeFireAndForget_WithErrorMessageFormat_FormatsMessage()
152159
{
153160
string? announced = null;
154161

155-
Task faultedTask = Task.Run(() => throw new Exception("boom"));
162+
Task faultedTask = Task.Run(
163+
() => throw new Exception("boom"),
164+
TestContext.Current.CancellationToken);
156165

157166
faultedTask.SafeFireAndForget(
158167
announceAction: msg => announced = msg,
159168
errorMessageFormat: "錯誤:{0}");
160169

161-
await Task.Delay(300);
170+
await Task.Delay(300, TestContext.Current.CancellationToken);
162171

163172
Assert.Equal("錯誤:boom", announced);
164173
}

0 commit comments

Comments
 (0)