Since I have converted my WCF methods to Async, my unit tests have failed, and I can't figure out the correct syntax to get them to work.
Cllient proxy class
 public interface IClientProxy
{
     Task DoSomething(CredentialDataList credentialData, string store);
}
service class
  public class CredentialSync : ICredentialSync
{
    private ICredentialRepository _repository;
    private IClientProxy _client;
    public CredentialSync()
    {
        this._repository = new CredentialRepository();
        this._client = new ClientProxy();
    }
    public CredentialSync(ICredentialRepository repository, IClientProxy client)
    {
        this._repository = repository;
        this._client = client;
    }
   public async Task Synchronise(string payrollNumber)
    {
        try
        {
            if (string.IsNullOrEmpty(payrollNumber))
            {
                .... some code
              }
            else
            {
                CredentialDataList credentialData = new CredentialDataList();
                List<CredentialData> credentialList = new List<CredentialData>();
                // fetch the record from the database
                List<GetCredentialData_Result> data = this._repository.GetCredentialData(payrollNumber);
                var pinData = this._repository.GetCredentialPinData(payrollNumber);
                // get the stores for this employee
                var storeList = data.Where(a => a.StoreNumber != null)
                    .GroupBy(a => a.StoreNumber)
                    .Select(x => new Store { StoreNumber = x.Key.ToString() }).ToArray();
                var credential = this.ExtractCredentialData(data, pinData, payrollNumber);
                credentialList.Add(credential);
                credentialData.CredentialList = credentialList;
                foreach (var store in storeList)
                {       
                  //this line causes an Object reference not set to an instance of an object error
                   await  _client.DoSomething(credentialData, store.StoreNumber);
                }
            }
        }
        catch (Exception ex)
        {
            throw new FaultException<Exception>(ex);
        }
    }
Test Class
 /// </summary>
[TestClass]
public class SynchTest
{
    private Mock<ICredentialRepository> _mockRepository;
    private Mock<IClientProxy> _mockService;
    [TestInitialize]
    public void Setup()
    {
       ... some setups for repository which work fine
    }
[TestMethod]      
    public async Task SynchroniseData_WithOneEmployee_CallsReplicateService()
    {
        this._mockService = new Mock<IClientProxy>();
        this._mockService.Setup(x=>x.DoSomething(It.IsAny<CredentialDataList>(), It.IsAny<string>()));
        // arrange
        string payrollNumber = "1";
        CredentialSync service = new CredentialSync(this._mockRepository.Object, this._mockService.Object);
        // act
        await service.Synchronise(payrollNumber);
        // assert                 
        this._mockService.VerifyAll();
    }
The error is when ClientProxy.DoSomething is called:
Object reference not set to an instance of an object
The parameters are both fine.
If I convert my ClientProxy.DoSomething method to a synchronous method
(public void DoSomething(...) )the code works fine, but I do need this to be called asynchronously
In this method, we set up an asynchronous mock call to the GetByIdAsync method from the IFakeDbArticle interface. This method returns the first article from the list we created inside the FakeDb class. When we mock an asynchronous method, instead of using a standard Return(...) method, we use the ReturnAsync(...)
You use the void return type in asynchronous event handlers, which require a void return type. For methods other than event handlers that don't return a value, you should return a Task instead, because an async method that returns void can't be awaited.
'Setup' mocks a method and 'Returns' specify what the mocked method should return.
DoSomething returns null instead of returning a Task, and so you get an exception when awaiting it. You need to specify when building the mock that it should return a Task.
In this case it seems that you can simply return an already completed task using Task.FromResult so the mock setup should look like this:
this._mockService.Setup(...).Returns(Task.FromResult(false));
Beginning with the next version of .Net (4.6) you can use Task.CompletedTask like this:
this._mockService.Setup(...).Returns(Task.CompletedTask);
                        You can reduce the amount of clutter in the code by using ReturnsAsync
this._mockService.Setup(...).ReturnsAsync(false);
This way you can remove the Task.FromResult part of the code
I think you need to return the Task from the DoSomething mock
this._mockService.Setup(x => x.DoSomething(It.IsAny<CredentialDataList>(), It.IsAny<string>()))
    .Returns(Task.FromResult<int>(0));
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With