Moq with Task await
.net, async-await, asynchronous, c#, moq
Solution
`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);
Problem
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