I've got a time-triggered Azure Function which I want to test with XUnit and MOQ.
While I know I need to call the Run
method of the class using an instance of the class say funTimeTriggeredObj
where
funTimeTriggered funTimeTriggeredObj = new funTimeTriggered(queueSchedulerMock.Object, telemetryHelperMock.Object)
like
funTimeTriggeredObj.Run(param1, param2, loggerMock.Object)
where
private Mock<ILogger> loggerMock = new Mock<ILogger>()
I'm not sure how should I mock the param1
& param2
which are TimerInfo
and ExecutionContext
objects respectively.
The reason why I'm asking is because neither 'TimerInfo' nor 'ExecutionContext' implements any interface which can be mocked.
Below is my actual function implementation. Any help whatsoever would be highly appreciated.
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;
}
}
}
If there are no undesired effects of using actual instance of those classes and you can actually initialize them then create actual instance and pass them to the function under test.
They do not have to be interfaces or mocked if using the actual instance(s) has no unwanted effects
//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
And since in this test case the timer is not even used by the function, it can be ignored altogether
//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