Reputation: 1
Hi I`m trying to unit test method with asynchronous web service call (asmx) . Code is as below. Problem is with mocking somehow, TaskCompletionSource .Should I use this pattern ?? Is there any way make it testable.
public async Task<Result> CreateConfAsync(byte[] sesja, Conference conference)
{
Result rez = new Result(-1,"error");
try
{
var confsStrXml = ConferenceHelper.createConfsXmlString(conference);
var tcs = new TaskCompletionSource<WsWynik>();
_proxy.KonferencjaZapiszCompleted += GetCreateConfAsyncCallBack;
_proxy.KonferencjaZapiszAsync(sesja, confsStrXml,tcs);
var wsWynik = await tcs.Task;
rez.status = wsWynik.status;
rez.message = wsWynik.status_opis;
if (rez.status != 0) SesjaExceptionCheck.SesjaCheckThrowIfError(rez.status, rez.message);
}
catch (Exception ex)
{
throw ex;
}
finally
{
_proxy.KonferencjaZapiszCompleted -= GetCreateConfAsyncCallBack;
}
return rez;
}
public void GetCreateConfAsyncCallBack(object sender, KonferencjaZapiszCompletedEventArgs e)
{
var tcs = (TaskCompletionSource<WsWynik>)e.UserState;
if (e.Cancelled)
{
tcs.TrySetCanceled();
}
else if (e.Error != null)
{
tcs.TrySetException(e.Error);
}
else
{
tcs.TrySetResult(e.Result);
}
}
I`ve try to mock TaskCompletionSource, but no result .
[TestMethod]
public async Task CreateConf_ShouldBeOk()
{
var conf = new Mock<Conference>();
var tcs = new TaskCompletionSource<WsWynik>();
tcs.SetResult(default(WsWynik));
_proxy.Setup(x => x.KonferencjaZapiszAsync(_sesja, It.IsAny<string>(),tcs))
.Raises(mock => mock.KoszykKonferencjaZapiszCompleted += null, new EventArgs());
ConferenceRepository confRep = new ConferenceRepository(_proxy.Object, _dictRep.Object);
var res = await confRep.CreateConfAsync(_sesja, conf.Object);
Assert.IsTrue(1 == 1);
}
Upvotes: 0
Views: 47
Reputation: 247551
A few things need to be addressed.
The task completion source cannot be mocked as it is created within the method under test. It is not needed to mock anyway.
Use argument matchers for the mocked proxy method so that is will invoke when passed the values from the method.
For the event being raised, the proper event argument needs to be passed with the mock in order for the system under test to behave as desired.
[TestMethod]
public async Task CreateConf_ShouldBeOk() {
//Arrange
var conf = new Mock<Conference>();
var eventArgs = new KonferencjaZapiszCompletedEventArgs(...) {
Result = //...,
//populate the necessary properties
};
_proxy
.Setup(_ => _.KonferencjaZapiszAsync(
It.IsAny<byte[]>(),
It.IsAny<string>(),
It.IsAny<TaskCompletionSource<WsWynik>>()
))
.Raises(_ => _.KoszykKonferencjaZapiszCompleted += null, eventArgs);
var repository = new ConferenceRepository(_proxy.Object, _dictRep.Object);
//Act
var result = await repository.CreateConfAsync(_sesja, conf.Object);
//Assert
Assert.IsNotNull(result);
Assert.AreEqual(result.status, expectedStatus);
Assert.AreEqual(result.message , expectedMessage);
//assert the expected values of the result members
}
Upvotes: 1