首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何为ExecuteReaderAsync编写shim?

如何为ExecuteReaderAsync编写shim?
EN

Stack Exchange QA用户
提问于 2021-10-13 10:10:15
回答 1查看 288关注 0票数 0

我有以下方法,并希望为其中所需的功能(包括ExecuteReaderAsync)编写shim:

代码语言:javascript
复制
public async Task<IEnumerable<ApplicationSetting>> LoadSettingsAsync(string[] keys)
{
    await using var sourceConnection = new SqlConnection(_options.Value.StoreConnectionString);
    await sourceConnection.OpenAsync();

    SqlCommand command =
        new SqlCommand(
            SqlStatements.SelectMultipleKeys(_options.Value.DefaultStoreTableName,
                _options.Value.DefaultStoreSchema), sourceConnection);
    command.AddArrayParameters(ColumnNames.Keys, keys);
    var reader = await command.ExecuteReaderAsync();

    List<ApplicationSetting> settings = new();
    while (await reader.ReadAsync())
        settings.Add(new ApplicationSetting(reader[ColumnNames.Key].ToString()!,
            reader[ColumnNames.Value].ToString(), reader[ColumnNames.Type].ToString()!));

    await reader.CloseAsync();
    await sourceConnection.CloseAsync();
    return settings;
}

测试方法:

代码语言:javascript
复制
[Fact]
public async Task LoadSettingsAsync_WhenCall_LoadApplicationSettings()
{
    using (ShimsContext.Create())
    {
        // Arrange
        var keys = new string[] { "key1", "key2" };

        // simulate a connection
        ShimSqlConnection.AllInstances.OpenAsyncCancellationToken = (connection, token) =>
        {
            return Task.FromResult(true);
        };
        //string commandText;

        // shim-Mock all called methods
        ShimSqlCommand.AllInstances.ExecuteReaderAsync = command =>
        {
            return Task.FromResult(???????????????????????);
        };
        var rowCounter = 0;
        ShimSqlDataReader.AllInstances.Read = (sender) =>
        {
            rowCounter++;
            return rowCounter <= 2;
        };

        ShimSqlConnection.AllInstances.Close = connection => { };

        // Act
        var ex = await Record.ExceptionAsync(() =>
            _myClass.LoadSettingsAsync(keys));

        // Assert
        ex.Should().BeNull();
    }
} 

我尝试Substitute.For<SqlDataReader>()来创建实例SqlDataReader,但是它抛出了System.InvalidOperationException

然后我尝试了这个代码:

代码语言:javascript
复制
ShimSqlCommand.AllInstances.ExecuteReaderAsync = async command =>
{
     return new ShimSqlDataReader();
};

但是它会在NullReferenceException行上抛出await reader.ReadAsync() (注意:阅读器有价值):

EN

回答 1

Stack Exchange QA用户

发布于 2022-09-08 09:46:30

以下是我所做的:

代码语言:javascript
复制
ShimSqlCommand.AllInstances.ExecuteReaderAsync = command => Task.FromResult((SqlDataReader)new ShimSqlDataReader());

ExecuteReaderAsync需要一个Task<SqlDataReader>作为返回类型。Task.FromResult()用于Task部分。ShimSqlDataReader是来自ShimBase<SqlDataReader>的派生类,您可以将它转换为SqlDataReader,而不存在任何问题。这个类包含在你不需要自己创建的赝品中。

注意:ShimSqlDataReader可以像这样直接使用:

代码语言:javascript
复制
ShimSqlCommand.AllInstances.ExecuteReader = command => new ShimSqlDataReader();

对于一个ExecuteReader垫片(没有async)。

票数 0
EN
页面原文内容由Stack Exchange QA提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://sqa.stackexchange.com/questions/49175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档