在測驗中,我正在創建多個執行緒,為了測驗賽車條件,我需要執行緒同時啟動,到目前為止一切都很好。但是當我斷言該方法已執行的次數時,如果失敗,因為它沒有等到所有執行緒都完成。
[Test]
public void Test_Racing_Condition()
{
//Arrange & Act
var threads = new Thread[20];
for (int i = 0; i < threads.Length; i )
{
thread[i] = new Thread(async () => await _memory.GetMemoryAsync());
}
foreach (Thread thread in threads)
{
thread.Start();
}
foreach (var thread in threads)
{
thread.Join();
}
//Assert
Mock.Assert(() => _memory.GetMemoryAsync(), Occurs.Exactly(20));
}
如何強制測驗在斷言之前等待所有執行緒?
我遇到的問題是斷言正在完成,在執行緒完成之前,因此測驗失敗。
uj5u.com熱心網友回復:
這里的問題是你在這里使用async void : new Thread(async () => await _memory.GetMemoryAsync())。一旦_memory.GetMemoryAsync()等待第一個未完成的等待,該方法將回傳并且執行緒完成其作業。
試試這個:
[Test]
public async Task Test_Racing_Condition()
{
//Arrange & Act
var tasks = new Task[20];
for (int i = 0; i < tasks.Length; i )
{
// Use Task.Run to return immediately.
// Not necessary in production code.
tasks[i] = Task.Run(_memory.GetMemoryAsync);
}
await Task.WhenAll(tasks);
//Assert
Mock.Assert(() => _memory.GetMemoryAsync(), Occurs.Exactly(20));
}
如果您真的需要它們盡可能地靠近彼此:
[Test]
public async Task Test_Racing_Condition()
{
//Arrange
using (var tcs = new TaskCompletionSource<object>())
{
var tasks = new Task[20];
for (int i = 0; i < tasks. Length; i )
{
// Use Task.Run to return immediately.
// Not necessary in production code.
tasks[i] = Task.Run(async () =>
{
await tcs.Task;
await _memory.GetMemoryAsync();
});
}
// Act
tcs.SetResult(null);
}
await Task.WhenAll(tasks);
//Assert
Mock.Assert(() => _memory.GetMemoryAsync(), Occurs.Exactly(20));
}
uj5u.com熱心網友回復:
通過 Nunit 測驗,我使用 DelayedConstraint。DelayedConstraint 延遲另一個約束的應用,直到經過一定的時間。在最簡單的形式中,它取代了代碼中睡眠的使用,但它也支持輪詢,這可能允許使用更長的最大時間,同時仍然盡可能快地保持測驗。
DelayedConstraint constraint = Is.True.After(delayInMilliseconds: 100, pollingInterval: 5);
Assert.That(() => _memory.GetMemoryAsync(), Occurs.Exactly(20), expr: constraint);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/511487.html
上一篇:呼叫TransactWriteItems操作時出現boto3錯誤:transactItems處的驗證錯誤:成員的長度必須小于或等于25
下一篇:在建構式中創建的模擬物件
