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
DoSomething
returnsnull
instead of returning aTask
, and so you get an exception when awaiting it. You need to specify when building the mock that it should return aTask
.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:Beginning with the next version of .Net (4.6) you can use
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 codeI think you need to return the
Task
from theDoSomething
mock