单元测试在C#,Moq中调用SAP异步Web服务

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单元测试在C#,Moq中调用SAP异步Web服务相关的知识,希望对你有一定的参考价值。

嗨,我试图用异步Web服务调用(asmx)单元测试方法。代码如下。问题是以某种方式嘲弄,TaskCompletionSource。我应该使用这种模式吗?有没有办法使它可测试。

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

我试图模拟TaskCompletionSource,但没有结果。

    [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);
    }
答案

有一些事情需要解决。

任务完成源不能被模拟,因为它是在被测方法中创建的。无论如何都不需要嘲笑。

使用参数匹配器作为模拟代理方法,以便在从方法传递值时调用。

对于引发的事件,需要使用模拟传递正确的事件参数,以使被测系统按照需要运行。

[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
}

以上是关于单元测试在C#,Moq中调用SAP异步Web服务的主要内容,如果未能解决你的问题,请参考以下文章

C#单元测试--如何使用moq.mock进行依赖注入

Moq + 单元测试 - System.Reflection.TargetParameterCountException:参数计数不匹配

如何使用MOQ进行单元测试

使用 moq 对实体框架进行单元测试

如何使用 XCTestCases 实现异步任务依赖?

单元测试之Mock(Moq)