Function is not called in xunit c# - c#

I created a unit test for an azure function which is below (azure funtion)
public class Processor
{
private readonly static TimeSpan _TimeSpan = new TimeSpan(0, 4, 30);
private readonly IHandler<Request> _Classifier;
public Processor(IHandler<Request> Classifier)
{
_Classifier = Classifier;
}
[FunctionName("Processor")]
public async Task Run([TimerTrigger("0 * * * * *", RunOnStartup = false)] TimerInfo myTimer)
{
await _Classifier.ProcessCall(new string[] { "AR" }, 100, _TimeSpan);
}
}
And in unit test checking a repository function is called or not.
public class ProcessorTests
{
private readonly Mock<IRepository> _RepositoryMock = new Mock<IRepository>();
private readonly Mock<IHandler<Request>> _Classifier;
public ProcessorTests()
{
_Classifier = new Mock<IHandler<Request>>();
}
private Processor GetSetup()
{
return new Processor(_Classifier.Object);
}
[Fact]
public async Task Getcall_check()
{
GivenCode();
var sut = GetSetup();
await sut.Run(null);
_RepositoryMock.Verify(x => x.GetCodeFinder(It.IsAny<IList<string>>(), It.IsAny<DateTimeOffset>(), It.IsAny<string>(), It.IsAny<int>()), Times.Once);
}
private void GivenCode()
{
_RepositoryMock
.Setup(m => m.GetCodeFinder(It.IsAny<IList<string>>() ,It.IsAny<DateTimeOffset>(), It.IsAny<string>(), It.IsAny<int>()))
.ReturnsAsync(new Response<Call>(false, null, Enumerable.Empty<CallOut>()));
}
}
unit test is failed . when I debug the issue, this function _Classifier.ProcessCall does not get called. I put some breakpoints inside the _Classifier.ProcessCall but it's not received there. GetCodeFinder function is actually inside the ProcessCall..
I don`t understand why it not called ? any help
public interface IHandler<TCode>
{
Task ProcessCallouts(IEnumerable<string> countryCodes, int batchSize, TimeSpan safeShutDownTimeSpan);
}
public class Handler<TCode> : IHandler<TCode>
{
private readonly IRepository _Repository;
private readonly IServiceV2<Code, TCode> _Service;
public Handler(
IRepository repository,
IServiceV2<Code, TCode> Service,
)
{
_Repository = repository;
_Service = Service;
}
public async Task Process(IEnumerable<string> countryCodes, int batchSize, TimeSpan safeShutDownTimeSpan)
{
var Response = await _Repository.GetCodeFinder(code, time, pageToken, batchSize);
}

Related

Can't debug async method even if I am awaiting

I have the following scenario:
in my Test class:
public class ControllerTests
{
private readonly MyClass aux;
private readonly Mock<IOrchestrator> _orchestrator;
public ControllerTests()
{
orchestrator = new();
aux = new MyClass(_orchestrator.Object);
}
[Fact]
public async Task MyTest()
{
var result = await aux.Start(new MyParameters());
result.Should().BeOfType<AcceptedResult>();
}
}
MyClass:
public class MyClass : ControllerBase
{
private readonly Orchestrator _orchestrator;
[HttpPost]
public async Task<IActionResult> Start([FromBody] MyParametera parameters)
{
var result = await _orchestrator.StartProcessAsync(parameters);
return Accepted(result);
}
}
and at the end the Orcherstrator class:
public class Orchestrator : IOrchestrator{
public async Task<Guid> StartProcessAsync(MyParameters parameters)
{
var guid = await MyLogic(parameters, async () => {
var manager = _SomeLogic.Get<SomeClass>();
await manager.StartAsync(parameters);
});
}
}
while debugging the test I notice I am not able to hit a breakpoint in the Orchestrator class at the StartProcessAsync method. But I am awaiting everything! What am I doing wrong? Thank you!

How to use LoggingBehaviour in Clean Architecture with .NET Core?

I use CleanArchitecture for my .NET Core project with Angular and I am trying to use LoggingBehaviour class located on CleanArchitecture/src/Application/Common/Behaviours/ in that project template as shown below:
namespace CleanArchitecture.Application.Common.Behaviours
{
public class LoggingBehaviour<TRequest> : IRequestPreProcessor<TRequest>
{
private readonly ILogger _logger;
private readonly ICurrentUserService _currentUserService;
private readonly IIdentityService _identityService;
public LoggingBehaviour(ILogger<TRequest> logger, ICurrentUserService currentUserService,
IIdentityService identityService)
{
_logger = logger;
_currentUserService = currentUserService;
_identityService = identityService;
}
public async Task Process(TRequest request, CancellationToken cancellationToken)
{
var requestName = typeof(TRequest).Name;
var userId = _currentUserService.UserId ?? string.Empty;
string userName = string.Empty;
if (!string.IsNullOrEmpty(userId))
{
userName = await _identityService.GetUserNameAsync(userId);
}
_logger.LogInformation("CleanArchitecture Request: {Name} {#UserId} {#UserName} {#Request}",
requestName, userId, userName, request);
}
}
}
However, I have no idea about how to use it properly as there is not an example usage in that solution template. Could you please clarify me on how to use it properly according to this template example?
You can use like below;
namespace CleanArchitecture.Application.UnitTests.Common.Behaviours
{
public class RequestLoggerTests
{
private readonly Mock<ILogger<CreateTodoItemCommand>> _logger;
private readonly Mock<ICurrentUserService> _currentUserService;
private readonly Mock<IIdentityService> _identityService;
public RequestLoggerTests()
{
_logger = new Mock<ILogger<CreateTodoItemCommand>>();
_currentUserService = new Mock<ICurrentUserService>();
_identityService = new Mock<IIdentityService>();
}
[Test]
public async Task ShouldCallGetUserNameAsyncOnceIfAuthenticated()
{
_currentUserService.Setup(x => x.UserId).Returns("Administrator");
var requestLogger = new LoggingBehaviour<CreateTodoItemCommand>(_logger.Object, _currentUserService.Object, _identityService.Object);
await requestLogger.Process(new CreateTodoItemCommand { ListId = 1, Title = "title" }, new CancellationToken());
_identityService.Verify(i => i.GetUserNameAsync(It.IsAny<string>()), Times.Once);
}
[Test]
public async Task ShouldNotCallGetUserNameAsyncOnceIfUnauthenticated()
{
var requestLogger = new LoggingBehaviour<CreateTodoItemCommand>(_logger.Object, _currentUserService.Object, _identityService.Object);
await requestLogger.Process(new CreateTodoItemCommand { ListId = 1, Title = "title" }, new CancellationToken());
_identityService.Verify(i => i.GetUserNameAsync(null), Times.Never);
}
}
}

XUnit unit tests for MassTransit consumer

I am using MassTransit 5.5.5 version and xunit 2.4.1
My consumer looks like this
public class StorageInformationConsumer : IConsumer<CreateStorageInformationSummary>
{
private readonly IBus _serviceBus;
private readonly USIntegrationQueueServiceContext _USIntegrationQueueServiceContext;
public StorageInformationConsumer(IBus serviceBus, USIntegrationQueueServiceContext USIntegrationQueueServiceContext)
{
_serviceBus = serviceBus;
_USIntegrationQueueServiceContext = USIntegrationQueueServiceContext;
}
public async Task Consume(ConsumeContext<CreateStorageInformationSummary> createStorageInformationSummarycontext)
{
//....
}
}
And my Test like this
public class StorageInformationConsumerTest
{
private readonly USIntegrationQueueServiceContext _dbContext;
private readonly Mock<IBus> _serviceBusMock;
private readonly StorageInformationConsumer _storageInformationConsumer;
public StorageInformationConsumerTest()
{
var options = new DbContextOptionsBuilder<USIntegrationQueueServiceContext>()
.UseInMemoryDatabase(databaseName: "InMemoryArticleDatabase")
.Options;
_dbContext = new USIntegrationQueueServiceContext(options);
_serviceBusMock = new Mock<IBus>();
_storageInformationConsumer = new StorageInformationConsumer(_serviceBusMock.Object, _dbContext);
}
[Fact]
public async void ItShouldCreateStorageInformation()
{
var createStorageInformationSummary = new CreateStorageInformationSummary
{
ClaimNumber = "C-1234",
WorkQueueItemId = 1,
StorageInformation = CreateStorageInformation(),
};
//How to consume
}
}
How to consume the CreateStorageInformationSummary message in order to call consumer, following doesn't work
var mockMessage = new Mock<ConsumeContext<CreateStorageInformationSummary>>(createStorageInformationSummary);
await _storageInformationConsumer.Consume(mockMessage.Object);
Since you have not clarified what is actually not working, the most I can provide is how to create the mock context and pass it to the subject method under test.
This is simple enough since ConsumeContext<T> is already an interface
[Fact]
public async Task ItShouldCreateStorageInformation() {
//Arrange
var createStorageInformationSummary = new CreateStorageInformationSummary {
ClaimNumber = "C-1234",
WorkQueueItemId = 1,
StorageInformation = CreateStorageInformation(),
};
//Mock the context
var context = Mock.Of<ConsumeContext<CreateStorageInformationSummary>>(_ =>
_.Message == createStorageInformationSummary);
//Act
await _storageInformationConsumer.Consume(context);
//Assert
//...assert the expected behavior
}
Also take note that the test has been updated to return async Task and not async void
Reference Moq Quickstart

I want to Create Xunit test for this controller. How can i do that

I have created small kind of xunit test case but I don't know how to create this controller which i have mention below.
public class PropertyController : ControllerBase
{
private readonly IMediator _mediator;
private readonly ILogger<PropertyController> _logger;
public PropertyController(IMediator mediator, ILogger<PropertyController> logger)
{
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task<IActionResult> AddProperty([FromBody] AddPropertyCommand command)
{
bool commandResult = false;
_logger.LogInformation(
"----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({#Command})",
command.GetGenericTypeName(),
nameof(command.ModifiedUserId),
command.ModifiedUserId,
command);
commandResult = await _mediator.Send(command);
if (!commandResult)
{
return BadRequest();
}
return Ok();
}
I have created like this. i have mock the dependency and create a test case for add command is working fine or not
public class PropertyControllerTest
{
private readonly PropertyController _it;
private readonly Mock<IMediator> _mediatorMock;
private readonly Mock<ILogger<PropertyController>> _loggerPropertycontrollerMock;
public PropertyControllerTest()
{
_mediatorMock = new Mock<IMediator>();
_loggerPropertycontrollerMock = new Mock<ILogger<PropertyController>>();
_it = new PropertyController(_mediatorMock.Object, _loggerPropertycontrollerMock.Object);
}
[Fact]
public void it_Should_add_information_successfully_and_returns_200_status_result()
{
//How can i write xunit test case. I'm creating like this
_mediatorMock.Setup(x => x.Send().Returns(property);
}
The test below covers the 200 status result - a similar test for bad requests would be very similar.
[Fact]
public void it_Should_add_information_successfully_and_returns_200_status_result()
{
// Arrange
var expected = new AddPropertyCommand();
_mediatorMock.Setup(x => x.Send(It.IsAny<AddPropertyCommand>())).Returns(true);
// Act
var actionResult = _it.AddProperty(expected);
// Assert
actionResult.ShouldBeAssignableTo<OkResult>();
_mediatorMock.Verify(x => x.Send(expected));
}
N.B. actionResult.ShouldBeAssignableTo<OkResult>(); is written using the Shouldly assertion framework, you can swap that out for anything you like. The one built into XUnit would be like this: Assert.IsType(typeof(OkResult), actionResult);

Property injection

I'm trying make a telegram bot with reminder. I'm using Telegram.Bot 14.10.0, Quartz 3.0.7, .net core 2.0. The first version should : get message "reminder" from telegram, create job (using Quartz) and send meaasage back in 5 seconds.
My console app with DI looks like:
Program.cs
static IBot _botClient;
public static void Main(string[] args)
{
// it doesn't matter
var servicesProvider = BuildDi(connecionString, section);
_botClient = servicesProvider.GetRequiredService<IBot>();
_botClient.Start(appModel.BotConfiguration.BotToken, httpProxy);
var reminderJob = servicesProvider.GetRequiredService<IReminderJob>();
reminderJob.Bot = _botClient;
Console.ReadLine();
_botClient.Stop();
// it doesn't matter
}
private static ServiceProvider BuildDi(string connectionString, IConfigurationSection section)
{
var rJob = new ReminderJob();
var sCollection = new ServiceCollection()
.AddSingleton<IBot, Bot>()
.AddSingleton<ReminderJob>(rJob)
.AddSingleton<ISchedulerBot>(s =>
{
var schedBor = new SchedulerBot();
schedBor.StartScheduler();
return schedBor;
});
return sCollection.BuildServiceProvider();
}
Bot.cs
public class Bot : IBot
{
static TelegramBotClient _botClient;
public void Start(string botToken, WebProxy httpProxy)
{
_botClient = new TelegramBotClient(botToken, httpProxy);
_botClient.OnReceiveError += BotOnReceiveError;
_botClient.OnMessage += Bot_OnMessage;
_botClient.StartReceiving();
}
private static async void Bot_OnMessage(object sender, MessageEventArgs e)
{
var me = wait _botClient.GetMeAsync();
if (e.Message.Text == "reminder")
{
var map= new Dictionary<string, object> { { ReminderJobConst.ChatId, e.Message.Chat.Id.ToString() }, { ReminderJobConst.HomeWordId, 1} };
var job = JobBuilder.Create<ReminderJob>().WithIdentity($"{prefix}{rnd.Next()}").UsingJobData(new JobDataMap(map)).Build();
var trigger = TriggerBuilder.Create().WithIdentity($"{prefix}{rnd.Next()}").StartAt(DateTime.Now.AddSeconds(5).ToUniversalTime())
.Build();
await bot.Scheduler.ScheduleJob(job, trigger);
}
}
}
Quartz.net not allow use constructor with DI. That's why I'm trying to create property with DI.
ReminderJob.cs
public class ReminderJob : IJob
{
static IBot _bot;
public IBot Bot { get; set; }
public async Task Execute(IJobExecutionContext context)
{
var parameters = context.JobDetail.JobDataMap;
var userId = parameters.GetLongValue(ReminderJobConst.ChatId);
var homeWorkId = parameters.GetLongValue(ReminderJobConst.HomeWordId);
await System.Console.Out.WriteLineAsync("HelloJob is executing.");
}
}
How can I pass _botClient to reminderJob in Program.cs?
If somebody looks for answer, I have one:
Program.cs (in Main)
var schedBor = servicesProvider.GetRequiredService<ISchedulerBot>();
var logger = servicesProvider.GetRequiredService<ILogger<DIJobFactory>>();
schedBor.StartScheduler();
schedBor.Scheduler.JobFactory = new DIJobFactory(logger, servicesProvider);
DIJobFactory.cs
public class DIJobFactory : IJobFactory
{
static ILogger<DIJobFactory> _logger;
static IServiceProvider _serviceProvider;
public DIJobFactory(ILogger<DIJobFactory> logger, IServiceProvider sp)
{
_logger = logger;
_serviceProvider = sp;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
IJobDetail jobDetail = bundle.JobDetail;
Type jobType = jobDetail.JobType;
try
{
_logger.LogDebug($"Producing instance of Job '{jobDetail.Key}', class={jobType.FullName}");
if (jobType == null)
{
throw new ArgumentNullException(nameof(jobType), "Cannot instantiate null");
}
return (IJob)_serviceProvider.GetRequiredService(jobType);
}
catch (Exception e)
{
SchedulerException se = new SchedulerException($"Problem instantiating class '{jobDetail.JobType.FullName}'", e);
throw se;
}
}
// get from https://github.com/quartznet/quartznet/blob/139aafa23728892b0a5ebf845ce28c3bfdb0bfe8/src/Quartz/Simpl/SimpleJobFactory.cs
public void ReturnJob(IJob job)
{
var disposable = job as IDisposable;
disposable?.Dispose();
}
}
ReminderJob.cs
public interface IReminderJob : IJob
{
}
public class ReminderJob : IReminderJob
{
ILogger<ReminderJob> _logger;
IBot _bot;
public ReminderJob(ILogger<ReminderJob> logger, IBot bot)
{
_logger = logger;
_bot = bot;
}
public async Task Execute(IJobExecutionContext context)
{
var parameters = context.JobDetail.JobDataMap;
var userId = parameters.GetLongValue(ReminderJobConst.ChatId);
var homeWorkId = parameters.GetLongValue(ReminderJobConst.HomeWordId);
await _bot.Send(userId.ToString(), "test");
}
}

Categories

Resources