[英]How to unit test azure function triggered by time? My test doesn't work
[英]Unit Test a Time Triggered Azure Function
我有一个时间触发的 Azure 函数,我想用 XUnit 和 MOQ 测试它。
虽然我知道我需要使用类的实例调用该类的Run
方法,但说funTimeTriggeredObj
where
funTimeTriggered funTimeTriggeredObj = new funTimeTriggered(queueSchedulerMock.Object, telemetryHelperMock.Object)
像
funTimeTriggeredObj.Run(param1, param2, loggerMock.Object)
在哪里
private Mock<ILogger> loggerMock = new Mock<ILogger>()
我不确定我应该如何模拟分别是TimerInfo
和ExecutionContext
对象的param1
和param2
。
我问的原因是因为“TimerInfo”和“ExecutionContext”都没有实现任何可以模拟的接口。
下面是我的实际功能实现。 任何帮助将不胜感激。
using System;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
public class funTimeTriggered
{
private string _invocationID;
private readonly IQueueScheduler _queueScheduler;
private readonly ITelemetryHelper _telemetryHelper;
public funTimeTriggered(IQueueScheduler queueScheduler, ITelemetryHelper telemetryHelper)
{
_queueScheduler = queueScheduler;
_telemetryHelper = telemetryHelper;
}
[FunctionName("funTimeTriggered")]
public async Task Run([TimerTrigger("0/10 * * * * *")]TimerInfo myTimer, ExecutionContext context, ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
try
{
_invocationID = context.InvocationId.ToString();
await _queueScheduler.SendEventsToServiceBusAndDeleteFromSQS();
}
catch (Exception ex)
{
log.LogError(ex.Message);
_telemetryHelper.LogException(ex);
throw ex;
}
}
}
如果使用这些类的实际实例没有不良影响,并且您可以实际初始化它们,然后创建实际实例并将它们传递给被测函数。
如果使用实际实例没有不良影响,则它们不必是接口或模拟
//Arrange
//...omitted for brevity
var param1 = new TimerInfo(...);
var param2 = = new ExecutionContext {
InvocationId = Guid.NewGuid()
};
//Act
await funTimeTriggeredObj.Run(param1, param2, loggerMock.Object);
//Assert
//...assert expected behavior
由于在这个测试用例中定时器甚至没有被函数使用,所以可以完全忽略它
//Arrange
//...omitted for brevity
var param1 = default(TimerInfo); //null
var param2 = = new ExecutionContext {
InvocationId = Guid.NewGuid()
};
//Act
await funTimeTriggeredObj.Run(param1, param2, loggerMock.Object);
//Assert
//...assert expected behavior
您可以将 Azure 函数的逻辑放在一个单独的类中,并为该类编写单元测试。
可以做的是集成测试,如果使用不同的触发器(例如 HTTP)创建了另一个函数,做同样的事情。
设置是对的。 但是,与其尝试模拟 TimerInfo 和 ExecutionContext 或实现它们,不如简单地发送 null,因为您不在函数中使用它们。
我有我需要做的类似测试。 虽然我使用了 FakeItEasy,但我希望这会帮助你(或其他人)。
使用的软件包:
<PackageReference Include="FakeItEasy" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.2.0" />
一些测试:
public class FunTimeTriggeredConstructorTests
{
private ITelemetryHelper _fakeITelemetryHelper;
private IQueueScheduler _fakeIQueueScheduler;
public FunTimeTriggeredConstructorTests()
{
_fakeITelemetryHelper= A.Fake<ITelemetryHelper >();
_fakeIQueueScheduler = A.Fake<IQueueScheduler>();
}
[Fact]
public void ShouldThrow_ArgumentNullException_When_IQueueScheduler_Is_Null()
{
_fakeIQueueScheduler = null;
Assert.Throws<ArgumentNullException>(() => new FunTimeTriggered(_fakeITelemetryHelper, _fakeIQueueScheduler));
}
}
public class RunTests
{
private ITelemetryHelper _fakeITelemetryHelper;
private IQueueScheduler _fakeIQueueScheduler;
private TimerInfo _fakeTimerInfo;
private ExecutionContext _fakeExecutionContext;
private ILogger _fakeILogger;
private FunTimeTriggered _funTimeTriggered;
public RunTests()
{
_fakeITelemetryHelper= A.Fake<ITelemetryHelper>();
_fakeTimerInfo = A.Fake<TimerInfo>();
_fakeIQueueScheduler = A.Fake<IQueueScheduler>();
_fakeExecutionContext = A.Fake<ExecutionContext>();
_fakeILogger = A.Fake<ILogger>();
_funTimeTriggered = new FunTimeTriggered(_fakeITelemetryHelper, _fakeIQueueScheduler);
}
[Fact]
public async Task ShouldCall_IQueueScheduler_SendEventsToServiceBusAndDeleteFromSQS_AtMost_Once()
{
A.CallTo(() => _fakeExecutionContext.InvocationId).Returns("");
await FunTimeTriggered.Run(_fakeTimerInfo, _fakeExecutionContext, _fakeILogger);
A.CallTo(() => _queueScheduler.SendEventsToServiceBusAndDeleteFromSQS()).MustHaveHappenedOnceExactly();
}
}
// Arrange
TimerSchedule schedule = new DailySchedule("2:00:00");
TimerInfo timerInfo = new TimerInfo(schedule, It.IsAny<ScheduleStatus>(), false);
// Act
await _functions.TimerTrigerFunction(timerInfo, _durableOrchestrationClient.Object, _log.Object);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.