【问题标题】:Cannot convert async lambda expression to delegate无法将异步 lambda 表达式转换为委托
【发布时间】:2018-08-21 07:26:20
【问题描述】:

我正在为 MS Bot 对话框设置单元测试,但出现以下错误,不知道如何解决。任何人都可以帮忙吗?谢谢

错误 CS4010 无法将异步 lambda 表达式转换为委托类型“Task<HttpOperationResponse<BotData>>”。异步 lambda 表达式可能返回 void、Task 或 Task<T>,它们都不能转换为 'Task<HttpOperationResponse<BotData>>'。 D3DirectlineBot.UnitTests C:\Repos\D3DirectlineBot\D3DirectlineBot.UnitTests\MockConnectorFactory.cs 109 活动

模拟类

public Mock<StateClient> MockIBots(MockConnectorFactory mockConnectorFactory)
{
    var botsClient = new Moq.Mock<StateClient>(MockBehavior.Loose);

    botsClient.Setup(d => d.BotState.SetConversationDataWithHttpMessagesAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<BotData>(), It.IsAny<Dictionary<string, List<string>>>(), It.IsAny<CancellationToken>()))
        .Returns<string, string, BotData, Dictionary<string, List<string>>, CancellationToken>(async (channelId, conversationId, data, headers, token) =>
        {
            return await mockConnectorFactory.UpsertData(channelId, null, conversationId, BotStoreType.BotConversationData, data);
        });

        return botsClient;
    }

UpsertData 类

protected async Task<HttpOperationResponse<object>> UpsertData(string channelId, string userId, string conversationId, BotStoreType storeType, BotData data)
{
    var _result = new HttpOperationResponse<object>();
    _result.Request = new HttpRequestMessage();
    try
    {
        var address = AddressFrom(channelId, userId, conversationId);
        await memoryDataStore.SaveAsync(address, storeType, data, CancellationToken.None);
    }
    catch (HttpException e)
    {
        _result.Body = e.Data;
        _result.Response = new HttpResponseMessage { StatusCode = HttpStatusCode.PreconditionFailed };
        return _result;
    }
    catch (Exception)
    {
        _result.Response = new HttpResponseMessage { StatusCode = HttpStatusCode.InternalServerError };
        return _result;
    }
    _result.Body = data;
    _result.Response = new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
    return _result;
}

【问题讨论】:

    标签: c# unit-testing moq


    【解决方案1】:

    你应该直接返回任务而不等待它:

    return mockConnectorFactory.UpsertData(channelId, null, conversationId, BotStoreType.BotConversationData, data);
    

    【讨论】:

    • 现在这个错误 CS0029 无法将类型 'System.Threading.Tasks.Task>' 隐式转换为 'Microsoft.Rest.HttpOperationResponse' D3DirectlineBot.UnitTests C:\Repos\D3DirectlineBot\D3DirectlineBot.UnitTests\MockConnectorFactory.cs 104 活动
    • 这个错误错误 CS4010 无法将异步 lambda 表达式转换为委托类型“任务>”。异步 lambda 表达式可能返回 void、Task 或 Task,它们都不能转换为 'Task>'。 D3DirectlineBot.UnitTests C:\Repos\D3DirectlineBot\D3DirectlineBot.UnitTests\MockConnectorFactory.cs 135 活动
    • 您应该在此处删除 async 关键字:CancellationToken>(async (channelId
    • 删除了异步。但是没有两个解决上面提到的错误
    【解决方案2】:

    UpsertData 类:将HttpOperationResponse&lt;object&gt; 更改为HttpOperationResponse&lt;Botdata&gt;

    protected async Task<HttpOperationResponse<Botdata>> UpsertData(string channelId, string userId, string conversationId, BotStoreType storeType, BotData data)
    {
        var _result = new HttpOperationResponse<Botdata>();
        _result.Request = new HttpRequestMessage();
        try
        {
            var address = AddressFrom(channelId, userId, conversationId);
            await memoryDataStore.SaveAsync(address, storeType, data, CancellationToken.None);
        }
        catch (HttpException e)
        {
            _result.Body = data;
            _result.Response = new HttpResponseMessage { StatusCode = HttpStatusCode.PreconditionFailed };
            return _result;
        }
        catch (Exception)
        {
            _result.Response = new HttpResponseMessage { StatusCode = HttpStatusCode.InternalServerError };
            return _result;
        }
        _result.Body = data;
        _result.Response = new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
        return _result;
    }
    

    MockConnectionFactory 类:删除了@DmitryBogatykh 提到的asyncawait

        botsClient.Setup(d => d.BotState.SetConversationDataWithHttpMessagesAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<BotData>(), It.IsAny<Dictionary<string, List<string>>>(), It.IsAny<CancellationToken>()))
            .Returns((string channelId, string conversationId, BotData data, Dictionary<string, List<string>> headers, CancellationToken token) =>
            {
                return  mockConnectorFactory.UpsertData(channelId, null, conversationId, BotStoreType.BotConversationData, data);
            });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-18
      • 2016-04-15
      • 1970-01-01
      • 2019-12-08
      • 2018-02-17
      • 1970-01-01
      相关资源
      最近更新 更多