[英]Error in Azure Function Xunit Mock test : Expected invocation on the mock exactly 1 times, but was 0 times
我使用下面的時間觸發代碼創建了一個 azure 函數。 我對 azure 函數和 xunit 非常陌生。 我在一些博客的幫助下創建了兩者。 我在 C# 中使用 Xunit 編寫了一個簡單的單元測試。 但它返回一個錯誤。 我試圖解決這個問題,但對我不起作用..請幫助我
public class DeleteJob
{
private readonly IStore _store;
public DeleteJob(IStore store, ILogger<DeleteJob> log)
{
_store = store;
_log = log;
}
[Function("DeleteJob")]
public async Task Run([TimerTrigger("0 */5 * * * *", RunOnStartup = false)] MyInfo myTimer)
{
var canceltoken = new CancellationTokenSource(TimeSpan.FromMinutes(8));
var deleteDate = DateTime.UtcNow.AddMonths(-6);
try
{
await DeleteBlobMetadata(deleteDate, canceltoken.Token);
}
catch (OperationCanceledException)
{
_log.LogInformation("Function ran out of time");
}
}
private async Task DeleteBlobMetadata(DateTime deleteDate, CancellationToken canceltoken)
{
try
{
if (cancellationToken.IsCancellationRequested)
return;
var BlobUrls = await _store.GetBlobBeforeDate(Constants.ContainerName, deleteDate);
foreach (var blobName in BlobUrls)
{
if (cancellationToken.IsCancellationRequested)
return;
await _store.DeleteBlobAsync(Constants.ContainerName, blobName);
}
}
catch (Exception e)
{
_log.LogError($"Exception when deleting attachments: \n{e}");
}
以下是單元測試
public class DeleteTest
{
private readonly Mock<IStore> _StoreMock;
private Mock<ILogger<DeleteJob>> _logMock;
public DeleteTest()
{
_StoreMock = new Mock<IStore>();
_logMock = new Mock<ILogger<DeleteJob>>();
}
[Fact]
public async Task DeleteBlobOlderThan6Months_ShouldDelete()
{
SetupDeletionSuccessful(true);
SetupDeleteBlobSetup();
var sut = GetSut();
await sut.Run(myTimer: null);
_StoreMock.Verify(m => m.GetBlobBeforeDate(It.IsAny<string>(),It.IsAny<DateTime>()), Times.Exactly(1));
_StoreMock.Verify(m => m.DeleteAttachmentAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(1));
}
private void SetupDeleteBlobSetup()
{
_StoreMock.Setup(m => m.GetBlobBeforeDate(It.IsAny<string>(),It.IsAny<DateTime>()))
.ReturnsAsync(new List<string> { "someUrl" });
}
private void SetupDeletionSuccessful(bool successfulDeletion)
{
_StoreMock.Setup(m => m.DeleteAttachmentAsync(It.IsAny<string>(), It.IsAny<string>())).ReturnsAsync(successfulDeletion);
}
錯誤是
Expected invocation on the mock exactly 1 times, but was 0 times:
m => m.GetBlobBeforeDate(It.IsAny<string>(), It.IsAny<DateTime>())
錯誤信息是完全正確的。 在您的測試中,不會調用GetBlobBeforeDate()
:
在您的測試設置中, GetBlobBeforeDate
方法返回一個空列表:
_StoreMock.Setup(m => m.GetBlobBeforeDate(It.IsAny<string>(),It.IsAny<DateTime>()))
.ReturnsAsync(new List<string>());
這意味着在您的函數中將沒有要刪除的 blob url。 因為在您的函數中,您刪除了blobUrl
返回的所有GetBlobBeforeDate
。 沒有項目 => 沒有可刪除的內容。
如果您希望您的測試驗證DeleteAttachmentAsync
在您需要新設置時被調用。 例如:
_StoreMock.Setup(m => m.GetBlobBeforeDate(It.IsAny<string>(),It.IsAny<DateTime>()))
.ReturnsAsync(new List<string> { "someUrl" });
編輯:
更重要的是,這次在您的代碼中您調用:
await _store.DeleteBlobAsync(Constants.AttachmentContainerName, blobName);
但相應的 Mock 設置應該是:
_StoreMock.Setup(m => m.DeleteAttachmentAsync(It.IsAny<string>(), It.IsAny<string>())).ReturnsAsync(successfulDeletion);
如您所見,您將蘋果與橙子進行比較。 錯誤仍然正確:永遠不會調用DeleteAttachmentsAsync
。
同樣在您的代碼中,您同時使用了Constants.ContainerName
和Constants.AttachmentContainerName
這似乎也是錯誤的。
我建議將您的 Mocks 設置得更明確一些,並包含相應的容器名稱。 例如:
_StoreMock.Setup(m => m.GetBlobBeforeDate(Constants.ContainerName, It.IsAny<DateTime>()))
.ReturnsAsync(new List<string> { "someUrl" });
這樣,mock 還將驗證是否已使用預期的containerName
參數值調用了該方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.