Mugurel
Mugurel

Reputation: 246

Unit test Hangfire with NSubstitute

I am trying to unit test my class which includes a background job. So far my method which I am testing Enqueues a job and looks like this:

public void SendSms(SmsContent content){
      .... 
      _backgroundJobClient.Enqueue<ISms>(x => x.Send(content));
      ....
}

My first unit test check if BackgroundJobClient is called and looks like this:

 Assert.Equal(1,_backgroundJobClient.ReceivedCalls().Count());
  

All works fine but now I want to check all the parameters if the are correctly sent. I was looking over the HangFire documentation but I couldn't figure that out how can be teste with NSubstitute.

Thank you!

Upvotes: 0

Views: 2134

Answers (3)

to verify that the parameters are correctly passed to the background job, you can mock the Enqueue method and register the called job in a list. Here is how you can do it using NSubstitute:

private void ConfigureBackgroundJobClientMock(IServiceCollection services)
{
    var substitute = Substitute.For<IBackgroundJobClient>();
    substitute.Enqueue<ISms>(x => x.Send(default))
        .ReturnsForAnyArgs(x =>
        {
            JobsHangfire.Add(x.Arg<Job>());
            return Guid.NewGuid().ToString();
        });

    services.AddSingleton<IBackgroundJobClient>(x => substitute);
}

In this example, JobsHangfire is a List located in your test class. This list will store the jobs enqueued during your tests. You can then access these jobs and verify their parameters in your unit test.

Here’s an example of how to use this in your test method:

[Fact]
public async Task Your_Test_Method()
{
    // Your arrange and act
    
    // verify the enqueued job
    JobsHangfire.Count.ShouldBe(1);
    var job = JobsHangfire.First();
    // verify the method
    var method = typeof(ISms).GetMethod(nameof(ISms.Send));
    job.Method.ShouldBe(method);
    // verify the arguments
    job.Args[0].ShouldBe(your_parameter);
}

Upvotes: -1

David Tchepak
David Tchepak

Reputation: 10484

Based on the example in the docs you should be able to test it using something like this:

/* Moq example:
client.Verify(x => x.Create(
    It.Is<Job>(job => job.Method.Name == "CheckForSpam" && job.Arguments[0] == comment.Id.ToString()),
    It.IsAny<EnqueuedState>());
*/

// Ported to NSubstitute:
_backgroundJobClient.Received().Create(
    Arg.Is<Job>(job => job.Method.Name == "CheckForSpam" && job.Arguments[0] == comment.Id.ToString()),
    Arg.Any<EnqueuedState>()
);

This is only based on the documented example. The exact arg matching code you need will depend on the specific types you are using.

Upvotes: 1

Ramin Bateni
Ramin Bateni

Reputation: 17425

Use this code:

_backgroundJobClient.ReceivedWithAnyArgs()
                   .Enqueue<ISms>(x => x.Send(default));

Upvotes: 2

Related Questions