thomsan
thomsan

Reputation: 483

Hangfire recurring job with NSubstitute

I need to unit test my hangifre recurring job with NSubstitute, my service class as follows, now I need to run test for it.

public class ItemService : IItemService, IJobConfigurationService
 {
     private readonly IItemRepository itemRepository;
     private readonly ISettingRepository settingRepository;
     private readonly ILogger<ItemService> logger;

     public ItemService(IItemRepository itemRepository
         ,ISettingRepository settingRepository
         ,ILogger<ItemService> logger)
     {
         this.itemRepository = itemRepository;
         this.settingRepository = settingRepository;
         this.logger = logger;
     }

     public void ConfigureJob(string cronExpression)
     {
         RecurringJob.AddOrUpdate("PermanentlyDeleteItemsAsync", () =>
             PermanentlyDeleteItemsAsync(), cronExpression);
     }

     public async Task PermanentlyDeleteItemsAsync()
     {
         //some logic here
     }
 }

I tried my unit test method something like this,

[Fact]
public async Task ConfigureJob_AddsOrUpdateRecurringJobAsync()
{
    // Arrange
    var itemRepository = Substitute.For<IItemRepository>();
    var settingRepository = Substitute.For<ISettingRepository>();
    var logger = Substitute.For<ILogger<ItemService>>();
    var mockRecurringJobManager = Substitute.For<IRecurringJobManager>();

    var service = new ItemService(itemRepository, settingRepository, logger);
    string cronExpression = "0 * * * *"; // Every hour

    // Act
    service.ConfigureJob(cronExpression);

    // Assert
    mockRecurringJobManager.Received().AddOrUpdate(Arg.Any<string>(),
        () => service.PermanentlyDeleteItemsAsync(), cronExpression);
}

This didn't work and is this correct way to test it? because I'm new to Hangfire

Upvotes: 0

Views: 89

Answers (1)

J.Memisevic
J.Memisevic

Reputation: 1454

This will not work cuz IRecurringJobManager does not have method that with that contract! That is extension method.

Underline method looks like this:

void AddOrUpdate(
    [NotNull] string recurringJobId, 
    [NotNull] Job job, 
    [NotNull] string cronExpression, 
    [NotNull] RecurringJobOptions options);

You can see it on GitHub.

So your assert would look something like this:

 // Assert
        mockRecurringJobManager.Received().AddOrUpdate(Arg.Any<string>(), Arg.Any<Job>(), Arg.Any<string>(), Arg.Any<RecurringJobOptions>());

There is a option to create a Stub Or a Fake - where you would have your own implementation of IRecurringJobManager insted of substitute:

public class RecuringJobManagerFake : IRecurringJobManager
 {
     public List<Hangfire.Common.Job> Jobs = new List<Hangfire.Common.Job>(); 
     public void AddOrUpdate([NotNull] string recurringJobId, [NotNull] Hangfire.Common.Job job, [NotNull] string cronExpression, [NotNull] RecurringJobOptions options)
     {
         Jobs.Add(job);
     }

     public void RemoveIfExists([NotNull] string recurringJobId)
     {
         throw new System.NotImplementedException();
     }

     public void Trigger([NotNull] string recurringJobId)
     {
         throw new System.NotImplementedException();
     }
 }

You can save and check everything that IRecurringJobManager recieved.

Upvotes: 0

Related Questions