简体   繁体   中英

Unit test EAP Asynchronus WebSerivice call in C# , Moq

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);
    }

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM