Hangfire: unit testing with IBackgroundJobClient

Created on 5 Mar 2017  路  2Comments  路  Source: HangfireIO/Hangfire

This is how I inject IBackgroundJobClient into my app:

public class Handler : IHandler
{
    private readonly IBackgroundJobClient _client;
    public Handler(IBackgroundJobClient client)
    {
        _client = client;
    }

    public Perform(string arg1, . . .)
    {
         _client.Enqueue(() => Back(arg1, . . .))
    }

   public void Back(string arg1, . . .) { }
}

In my Perform unit testing, I want to verify if Enqueue was called:

var mock = new Mock<IBackgroundJobClient>();

// Act
handler.Perform(. . .)

 // Assert
 mock.Verify(client => client.Enqueue(It.IsAny<Expression<Func<Task>>>()));

currently I get invalid verify on a non-virtual member client.Enqueue. That's because Enqueue is a static member of IBackgroundJobClient.

Is there a workaround for my case above?

Most helpful comment

Actually, Enqueue() is an extension method. IBackgroundClient has very little you need to mock. Instead of using Moq, I have a manual stub for my testing:

public class FakeLoggingBackgroundJobClient : IBackgroundJobClient
{
   public Queue<Job> Jobs { get; } = new Queue<Job>();

   public string Create(Job job, IState state)
   {
      Jobs.Enqueue(job);
      return Jobs.Count.ToString();
   }

   public bool ChangeState(string jobId, IState state, string expectedState)
   {
      throw new NotImplementedException();
   }
}

Internally, Enqueue() calls Create(). My stub adds the job to the public Jobs property so I can assert on it in my tests. HTH.

All 2 comments

Actually, Enqueue() is an extension method. IBackgroundClient has very little you need to mock. Instead of using Moq, I have a manual stub for my testing:

public class FakeLoggingBackgroundJobClient : IBackgroundJobClient
{
   public Queue<Job> Jobs { get; } = new Queue<Job>();

   public string Create(Job job, IState state)
   {
      Jobs.Enqueue(job);
      return Jobs.Count.ToString();
   }

   public bool ChangeState(string jobId, IState state, string expectedState)
   {
      throw new NotImplementedException();
   }
}

Internally, Enqueue() calls Create(). My stub adds the job to the public Jobs property so I can assert on it in my tests. HTH.

Thanks @stajs. You are a genus. Internally, Enqueue() calls Create() - that's the important part i missed. With that i have Create() to play around with.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shorbachuk picture shorbachuk  路  4Comments

dealproc picture dealproc  路  3Comments

jeffsugden picture jeffsugden  路  4Comments

thurfir picture thurfir  路  4Comments

cottsak picture cottsak  路  3Comments