As part of the current project I’m working on we’ve got a service which offloads some email send tasks to a background worker running in Hangfire.

Creating the BackgroundJobClient directly in our service was throwing errors and didn’t allow us to test that it had actually been called so we moved to injecting a wrapper around the BackgroundJobClient which allowed us to Mock it as expected.

The below wrapper is inspired by the code here.

using Hangfire;

namespace MyProject.Shared.Contracts.Services
{
    public interface IHangfireWrapper
    {
        IBackgroundJobClient BackgroundJobClient { get; }
    }
}
using Hangfire;
using MyProject.Shared.Contracts.Services;

namespace MyProject.Infrastructure.Services
{
    public class HangfireWrapper : IHangfireWrapper
    {
        public IBackgroundJobClient BackgroundJobClient => new BackgroundJobClient(JobStorage.Current);
    }
}

This is used in the service like so.

// Call another handler to send email notification
_hangfireWrapper.BackgroundJobClient.Enqueue<MediatorHangfireBridge>(
    bridge => bridge.Send(
        "Change control notification",
        new ChangeControlNotificationCommand(validatedChangeControlDto)
        ));

From the comments on the offical Hangfire testing documentation it appears that the Enqueue and Schedule methods are extension methods that just use the Create method so in order to mock them we only need to mock the Create method.

_hangfireWrapper = new Mock<IHangfireWrapper>();
_hangfireWrapper.Setup(x => x.BackgroundJobClient.Create(It.IsAny<Job>(), It.IsAny<EnqueuedState>()));

And to verify we can do.

_hangfireWrapper.Verify(x => x.BackgroundJobClient.Create(It.IsAny<Job>(), It.IsAny<EnqueuedState>()));


0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *