Search code examples
c#tasknunitmoq

how to mock (awaitable) System.Threading.Tasks.Task<EMCResponse> in c#


I am novice to C# and have been trying to mock an object of type System.Threading.Tasks.Task<EMCResponse> but could not succeed. Can anyone help me how to mock?

public class PEProcessor : IPEProcessor
{
    public PEProcessor(IService service)
    {
        _proxy = service;
        _emUpdate = new EMUpdate(service);
    }


    public void CreateAddress(string modelName, string version, string name, MType mType, Address address, EMRequest request)
    {
        var response = _proxy.EMCreateAsync(request); // should return object of type (awaitable) System.Threading.Tasks.Task<EMCResponse>
        address.Id = Convert.ToInt32(response.Result.CM[0].Code);
    }

}

I am mocking as below

[Fact]
public void RequestIsVerifiable()
{

    //Arrange
    var wcfMock = new Mock<IService>();

    // wcfMock.Setup(x => x.EMCreateAsync(It.IsAny<EMCreateRequest>())).ReturnAsync(??);

    //Act
    var peProcessor = new PEProcessor(wcfMock.Object);
    peProcessor.CreateAddress(MoqData.ModelName, MoqData.version, MoqData.name,
        MoqData.MType, MoqData.AddressesList(), MoqData.EMRequest);

    //Assert
    wcfMock.Verify(service => service.EMCreateAsync(It.IsAny<EMCreateRequest>()), Times.AtLeastOnce);
}

Thanks in advance!!


Solution

  • Then you need to setup the mock to return the expected result so that the test can be exercised as expected.

    var response = new EMCResponse {
        //populate
    };
    
    wcfMock
        .Setup(x => x.EMCreateAsync(It.IsAny<EMCreateRequest>()))
        .ReturnAsync(response);
    

    That said, If it is possible to refactor that code to be async all the way and not have to make blocking calls.

    public class PEProcessor : IPEProcessor {
        public PEProcessor(IService service) {
            _proxy = service;
            _emUpdate = new EMUpdate(service);
        }    
    
        public async Task CreateAddress(string modelName, string version, string name, MType mType, Address address, EMRequest request) {
            var response = await _proxy.EMCreateAsync(request); // should return object of type (awaitable) System.Threading.Tasks.Task<EMCResponse>
            address.Id = Convert.ToInt32(response.CM[0].Code);
        }
    }
    

    The can be exercised as follows

    [Fact]
    public async Task RequestIsVerifiable() {
    
        //Arrange
        var wcfMock = new Mock<IService>();
    
        var response = new EMCResponse {
            //populate
        };
    
        wcfMock
            .Setup(x => x.EMCreateAsync(It.IsAny<EMCreateRequest>()))
            .ReturnAsync(response);
    
        var peProcessor = new PEProcessor(wcfMock.Object);
    
        //Act        
        await peProcessor.CreateAddress(MoqData.ModelName, MoqData.version, MoqData.name,
            MoqData.MType, MoqData.AddressesList(), MoqData.EMRequest);
    
        //Assert
        wcfMock.Verify(service => service.EMCreateAsync(It.IsAny<EMCreateRequest>()), Times.AtLeastOnce);
    }