[英]Imitation of OperationCanceledException scenario with unit-test fails
我使用 Moq 4.18.2 框架進行測試。
RtspClient
可能會從ConnectAsync
引發OperationCanceledException
。 所以,我嘗試測試這種情況。 我下面的測試拋出異常System.OperationCanceledException: The operation was canceled.
並且catch (OperationCanceledException)
永遠不會被執行。 我在這里做錯了什么?
RTSP
public interface IRtspClient : IDisposable
{
event EventHandler<RawFrame> FrameReceived;
Task ConnectAsync(CancellationToken token);
Task ReceiveAsync(CancellationToken token);
}
使用 IRtspClient 的方法
public async Task ConnectAsync(CancellationToken token = default)
{
try
{
await _rtspClient.ConnectAsync(token).ConfigureAwait(false);
OnConnected();
}
catch (OperationCanceledException ex)
{
OnConnectAttemptCanceled(ex);
throw;
}
catch(Exception ex)
{
OnFailedToConnect(ex);
throw;
}
}
測試
[TestMethod]
public async Task ConnectAsync_Canceled()
{
var expectedCanceledTaskStatus = true;
var tcs = new CancellationTokenSource();
tcs.Cancel();
var rtspClient = new Mock<IRtspClient>();
rtspClient
.Setup(_ => _.ConnectAsync(It.IsAny<CancellationToken>()))
.Returns(Task.FromException<OperationCanceledException>(new OperationCanceledException()))
var actualCanceledTaskStatus = false;
var camera = new MyCamera(rtspClient.Object);
camera.FailedToConnect += () => actualCanceledTaskStatus = true;
await camera.ConnectAsync(tcs.Token);
Assert.AreEqual(expectedCanceledTaskStatus, actualCanceledTaskStatus);
}
更新按照@Dai 的建議添加了缺少的await
,但我的測試仍然失敗。 任何人都可以看一下測試代碼嗎?
try{}
塊內await
返回的Task
- 否則同步控制將立即離開try{}
塊。delegate()
本地)中拋出的異常將不會被catch
。CancellationTokenSource
是IDisposable
,因此您應該更改ConnectAsync_Canceled
測試以將其包裝在using()
塊中。將您的代碼更改為:
public async Task ConnectAsync( CancellationToken cancellationToken = default )
{
try
{
await this.rtspClient.ConnectAsync(cancellationToken ).ConfigureAwait(false);
this.OnConnected();
}
catch( OperationCanceledException cEx )
{
this.OnConnectAttemptCanceled( cEx );
throw; // Re-throw so the `Task` representing *this method* (`ConnectAsync`) will report as Cancelled rather than Succeeded.
}
catch( Exception ex )
{
this.OnFailedToConnect( ex );
throw; // Re-throw so the `Task` representing *this method* (`ConnectAsync`) will report as Failed rather than Succeeded.
}
}
我發現了我的錯誤(除了@Dai 注意到的)。 我應該將我的測試中的await camera.ConnectAsync
放在try-catch
或使用Assert.ThrowsExceptionAsync
。 我選擇了后者。 這是工作測試:
[TestMethod]
public async Task ConnectAsync_Canceled()
{
var expectedTaskCanceledStatus = true;
var rtspClient = new Mock<IRtspClient>();
rtspClient
.Setup(_ => _.ConnectAsync(default(CancellationToken)))
.Returns(Task.FromException(new OperationCanceledException()));
var actualTaskCanceledStatus = false;
var camera = new MyCamera(rtspClient.Object);
camera.ConnectAttemptCanceled += () => actualTaskCanceledStatus = true;
await Assert.ThrowsExceptionAsync<OperationCanceledException>(async () => await camera.ConnectAsync());
Assert.AreEqual(expectedTaskCanceledStatus, actualTaskCanceledStatus);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.