簡體   English   中英

Azure Function Xunit Mock 測試中的錯誤:對模擬的預期調用正好 1 次,但為 0 次

[英]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.ContainerNameConstants.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM