首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Azure函数Xunit模拟测试中的错误:在模拟上期望调用精确1次,但为0次

Azure函数Xunit模拟测试中的错误:在模拟上期望调用精确1次,但为0次
EN

Stack Overflow用户
提问于 2022-06-11 20:21:23
回答 1查看 69关注 0票数 0

我用下面的时间触发代码创建了一个天蓝色函数。我非常新的天青功能和x单位。我在一些博客的帮助下创建了这两个网站。我在C#中使用Xunit编写了一个简单的单元测试。但它会返回一个错误。我试图解决这个问题,而不是为我工作。请帮帮我

代码语言:javascript
复制
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}");
        }

以下是单元式

代码语言:javascript
复制
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);
    }

错误是

代码语言:javascript
复制
 Expected invocation on the mock exactly 1 times, but was 0 times:
 m => m.GetBlobBeforeDate(It.IsAny<string>(), It.IsAny<DateTime>())
EN

回答 1

Stack Overflow用户

发布于 2022-06-11 20:40:33

错误信息是完全正确的。在您的测试中,GetBlobBeforeDate()不会被调用:

在测试设置中,返回空列表的GetBlobBeforeDate方法:

代码语言:javascript
复制
 _StoreMock.Setup(m => m.GetBlobBeforeDate(It.IsAny<string>(),It.IsAny<DateTime>()))
        .ReturnsAsync(new List<string>());

这意味着在您的函数中将没有要删除的blob url。因为在您的函数中,您删除了由blobUrl返回的所有GetBlobBeforeDate。没有项目=>,没什么要删除的。

如果您想让您的测试验证DeleteAttachmentAsync是否在您需要一个新的设置之后才被调用。例如:

代码语言:javascript
复制
 _StoreMock.Setup(m => m.GetBlobBeforeDate(It.IsAny<string>(),It.IsAny<DateTime>()))
        .ReturnsAsync(new List<string> { "someUrl" });

编辑:

更重要的是,这一次在您的代码中调用:

代码语言:javascript
复制
await _store.DeleteBlobAsync(Constants.AttachmentContainerName, blobName);

但是,对应的模拟设置应该是:

代码语言:javascript
复制
_StoreMock.Setup(m => m.DeleteAttachmentAsync(It.IsAny<string>(), It.IsAny<string>())).ReturnsAsync(successfulDeletion);

正如你所看到的,你在把苹果和橘子作比较。错误仍然是正确的:DeleteAttachmentsAsync从未被调用过。

此外,在代码中,您使用了两个Constants.ContainerName nad Constants.AttachmentContainerName,这似乎也是错误的。

我建议设置您的Mocks更明确一点,并包括相应的容器名称。例如:

代码语言:javascript
复制
_StoreMock.Setup(m => m.GetBlobBeforeDate(Constants.ContainerName, It.IsAny<DateTime>()))
                .ReturnsAsync(new List<string> { "someUrl" });

这样,模拟还将验证方法是否已使用预期的containerName参数值被调用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72587635

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档