Azure函数Xunit模拟测试中的错误:恰好在模拟上的预期调用1次,但为0次
我在下面的时间触发代码中创建了一个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}");
}
以下是Unitest
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>())
I created a azure function with the time trigger code below. Im very new to azure function and xunit. I created both with help of some blogs. I wrote a simple unit test using Xunit in C#. but it returns an error. I tried to solve the issue and not work for me.. Please help me
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(quot;Exception when deleting attachments: \n{e}");
}
Following is unittest
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);
}
Error is
Expected invocation on the mock exactly 1 times, but was 0 times:
m => m.GetBlobBeforeDate(It.IsAny<string>(), It.IsAny<DateTime>())
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
错误消息是完全正确的。在您的测试中,
getBlobBeforedate()
未被调用:在您的测试设置中
getBlobbeforedate
返回空列表的方法:这意味着在您的功能中,没有blob url url删除。 Because in your function you delete all
blobUrl
s that have been returned byGetBlobBeforeDate
. No items =>没什么可删除的。如果您希望测试验证
deletTachmentAsync
一旦您需要新设置,就可以准确调用。例如:编辑:
在更多内容上,这一次在您的代码中您致电:
但是相应的模拟设置是:
您可以看到,您将苹果与橙色进行比较。错误仍然正确:
deletTachmentsAsync
从未被调用。同样,在您的代码中,您也使用
常数。
我建议将您的模拟设置更加明确一些,并包括相应的容器名称。例如:
这样,模拟还将验证该方法已与预期
containerame
参数值调用。The error message is perfectly right. In your test the
GetBlobBeforeDate()
does not get called:In your test setup the
GetBlobBeforeDate
method to return an empty list:This means in you function there will be no blob url to delete. Because in your function you delete all
blobUrl
s that have been returned byGetBlobBeforeDate
. No items => nothing to delete.If you want your test to verify that
DeleteAttachmentAsync
gets called exactly once you need a new setup. For example:Edit:
On more thing, this time in your code you call:
But what should be the corresponding Mock setup is:
As you can see you are comparing apples to oranges. The error is still right:
DeleteAttachmentsAsync
never gets called.Also in your code you use both
Constants.ContainerName
nadConstants.AttachmentContainerName
which also seems wrong.I suggest to setup your Mocks a little bit more explicit and include the corresponding container name. For example:
This way the mock will also verify that the method has been called with the expected
containerName
parameter value.