I have web app which interact to WCF service with task-based async functions. When i was writing a unit tests i encountered with a problem about mocking async functions calls. I think no need to show unnecessary business logic because all fails only on these async calls. I've tried to do this in two ways, the first was:
[TestMethod]
public async Task GetAndSentSentinelList_AddedTest()
{
var mockRemoteClient = new Mock<IRemoteManager>();
mockRemoteClient.Setup(method => method.GetSentinelListAsync(new GetSentinelListRequest()))
.Returns(Task.FromResult(new GetSentinelListResponse(new RemoteManager.SentinelItem[4]
{
new RemoteManager.Item() {Id = "Identity_Host"},
new RemoteManager.Item() {Id = "Nose_Host"},
new RemoteManager.Item() {Id = "Sunny_Host"},
new RemoteManager.Item() {Id = "Ups_Supsu"}
})));
var rep = new Repository(hub)
{
Client = mockRemoteClient.Object,
Sentinels = new List<SentinelItem>()
{
new Item() {Id = "Identity_Host"},
new Item() {Id = "Nose_Host"},
new Item() {Id = "Sunny_Host"}
}
};
var res = await rep.Client.GetSentinelListAsync(new GetSentinelListRequest());
//Assert
Assert.IsNotNull(res );
}
The next was:
[TestMethod]
public async Task GetAndSentSentinelList_AddedTest()
{
//Arrange
var tcs = new TaskCompletionSource<GetSentinelListResponse>();
var expectedResult = new GetSentinelListResponse(new RemoteManager.SentinelItem[4]
{
new RemoteManager.Item() {Id = "Identity_Host"},
new RemoteManager.Item() {Id = "Nose_Host"},
new RemoteManager.Item() {Id = "Sunny_Host"},
new RemoteManager.Item() {Id = "Ups_Supsu"}
});
tcs.SetResult(expectedResult);
var mockRemoteClient = new Mock<IRemoteManager>();
mockRemoteClient.Setup(method => method.GetSentinelListAsync(new GetSentinelListRequest()))
.Returns(tcs.Task);
var rep = new Repository(hub)
{
Client = mockRemoteClient.Object,
Sentinels = new List<SentinelItem>()
{
new Item() {Id = "Identity_Host"},
new Item() {Id = "Nose_Host"},
new Item() {Id = "Sunny_Host"}
}
};
var res = await rep.Client.GetSentinelListAsync(new GetSentinelListRequest());
Assert.IsNotNull();
}
Perhaps i'll add generated code, cause at now i confused why it isn't working properly, generated abstract interface IRemoteManager:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="RemoteManager.IRemoteManager", CallbackContract=typeof(Web_Manager.RemoteManager.IRemoteManagerCallback))]
public interface IRemoteManager
{
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IRemoteManager/GetSentinelList", ReplyAction="http://tempuri.org/IRemoteManager/GetSentinelListResponse")]
System.Threading.Tasks.Task<Web_Manager.RemoteManager.GetSentinelListResponse> GetSentinelListAsync(Web_Manager.RemoteManager.GetSentinelListRequest request);
}
And concrete generated implementation of IRemoteManager, - RemoteManagerClient:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class RemoteManagerClient : System.ServiceModel.DuplexClientBase<Web_Manager.RemoteManager.IRemoteManager>, Web_Manager.RemoteManager.IRemoteManager {
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
System.Threading.Tasks.Task<Web_Manager.RemoteManager.GetSentinelListResponse> Web_Manager.RemoteManager.IRemoteManager.GetSentinelListAsync(Web_Manager.RemoteManager.GetSentinelListRequest request) {
return base.Channel.GetSentinelListAsync(request);
}
}