Search code examples
c#asp.netunit-testingasp.net-corexunit

How to write xUnit Test for a method which calls another method in its body?


This is the class contains EnqueueJobAsync method which I want to write test for it :

public class ConsumerBaseForTesting
{
    protected IJobStore JobStore { get; private set; }

    public ConsumerBaseForTesting(IJobStore jobStore)
    {
        JobStore = jobStore;
    }

    public async Task<IJob> EnqueueJobAsync(IJob job)
        => await JobStore.CreateAsync(job);
}

This is my test which Fails and its actual return is always NULL !

public class ConsumerBaseTest
{


    private readonly Mock<IJobStore> _moqIJobStore;
    private readonly ConsumerBaseForTesting _consumerBase;

    public ConsumerBaseTest()
    {
        _moqIJobStore = new Mock<IJobStore>();
        _consumerBase = new ConsumerBaseForTesting(_moqIJobStore.Object);
    }


    [Theory]
    [ClassData(typeof(JobClassForTesting))]
    public async Task EnqueueJobAsyncTest(IJob job)
    {
        var jobResult = await _consumerBase.EnqueueJobAsync(job);

        Assert.Equal(job, jobResult);
    }
    
}

Solution

  • The mock needs to be setup to do two things in order to replicate the expected behavior.

    It needs to return the passed job in a completed task.

    //...
    
    public ConsumerBaseTest() {
        _moqIJobStore = new Mock<IJobStore>();
        _consumerBase = new ConsumerBaseForTesting(_moqIJobStore.Object);
    
        //setup the mock to capture and return the job when CreateAsync(IJob job) is invoked
        _moqIJobStore
            .Setup(_ => _.CreateAsync(It.IsAny<IJob>()))
            .Returns((IJob x) => Task.FromResult(x));     }
    
    //...
    

    .Returns((IJob x) => Task.FromResult(x)) captures the argument and returns completed Task<IJob>