【问题标题】:How to Shim ExecuteReader with MS Fake如何使用 MS Fake 填充 ExecuteReader
【发布时间】:2026-02-12 03:45:01
【问题描述】:

我正在尝试测试下面的方法但是我在using (var reader = command.ExecuteReader()) 行中遇到错误,即必须打开连接并且可用。我无法填充此方法并返回假阅读器。

测试方法

 public EmailTemplateFilterModel[] GetEmailTemplateFilters()
        {
            var filterList = new List<EmailTemplateFilterModel>();

            using (var connection = new SqlConnection(_clientConnString))
            using (var command = connection.CreateCommand("cspGetInvoiceTemplateFilterCollections"))
            {
                if (connection.State != ConnectionState.Open)
                    connection.Open();

                using (var reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var filter = new EmailTemplateFilterModel
                        {
                            ParmId = (int)reader["InvoiceEmailMapParmId"],
                            ParmName = (string)reader["ParmName"],
                            DatabaseDataType = (string)reader["DbDataType"],
                            ControlType = (string)reader["ControlType"],
                            StoredValue = (string)reader["StoredValue"],
                            DisplayedValue = (string)reader["DisplayedValue"]
                        };

                        filterList.Add(filter);
                    }
                }
            }
            return filterList.ToArray();
        }

单元测试

 [Test()]
        public void GetEmailTemplateFiltersTest()
        {
            using (ShimsContext.Create())
            {
                var rowCounter = 0;

                //ARRANGE
                ShimSqlConnection.AllInstances.Open = (sender) => { };
                ShimSqlConnection.AllInstances.StateGet = (sender) => { return ConnectionState.Open; };
                //ShimSqlCommand.AllInstances.ExecuteReader = (sender) => new Mock<SqlDataReader>().Object;

                ShimSqlDataReader.ConstructorSqlCommandCommandBehavior = (@this, p1, p2) =>
                {
                    var shim = new ShimSqlDataReader(@this)
                    {

                        // ValueGet = () => -5
                    };
                };


                ShimSqlDataReader.AllInstances.Read = (sender) =>
                {
                    rowCounter++;
                    return rowCounter <= 2;
                };

                ShimSqlDataReader.AllInstances.ItemGetString = (sender, coloumnName) =>
                {
                    if (rowCounter == 1)
                    {
                        switch (coloumnName)
                        {
                            case "InvoiceEmailMapParmId":
                                return 1;
                            case "ParmName":
                                return "Param1";
                            default:
                                return "SomeStrigValue";
                        }
                    }
                    else if (rowCounter == 2)
                    {
                        switch (coloumnName)
                        {
                            case "InvoiceEmailMapParmId":
                                return 1;
                            case "ParmName":
                                return "Param1";
                            default:
                                return "SomeStrigValue";
                        }
                    }
                    else
                    {
                        return string.Empty;
                    }
                };

                //ACT
                var filterList = _sut.GetEmailTemplateFilters();

                //ASSERT
                Assert.That(filterList.Length, Is.EqualTo(rowCounter));

            }
        }

【问题讨论】:

    标签: c# microsoft-fakes shim


    【解决方案1】:
      [Test()]
            public void GetEmailTemplateFiltersTest()
            {
                using (ShimsContext.Create())
                {
                    #region ARRANGE
                    var rowCounter = 0;
    
                    ShimSqlConnection.AllInstances.Open = (sender) => { };
                    ShimSqlConnection.AllInstances.StateGet = (sender) => ConnectionState.Open;
                    ShimSqlCommand.AllInstances.ExecuteReader = (sender) => new ShimSqlDataReader();
                    ShimDbDataReader.AllInstances.Dispose = (sender) => { };
                    ShimDbDataReader.AllInstances.DisposeBoolean = (sender, p1) => { };
    
                    ShimSqlDataReader.AllInstances.Read = (sender) =>
                    {
                        rowCounter++;
                        return rowCounter <= 2;
                    };
    
                    ShimSqlDataReader.AllInstances.ItemGetString = (sender, coloumnName) =>
                    {
                        if (rowCounter == 1)
                        {
                            switch (coloumnName)
                            {
                                case "InvoiceEmailMapParmId":
                                    return 1;
                                case "ParmName":
                                    return "Param1";
                                default:
                                    return "SomeStrigValue";
                            }
                        }
                        else if (rowCounter == 2)
                        {
                            switch (coloumnName)
                            {
                                case "InvoiceEmailMapParmId":
                                    return 1;
                                case "ParmName":
                                    return "Param1";
                                default:
                                    return "SomeStrigValue";
                            }
                        }
                        else
                        {
                            return string.Empty;
                        }
                    }; 
                    #endregion
    
                    //ACT
                    var filterList = _sut.GetEmailTemplateFilters();
    
                    //ASSERT
                    Assert.That(filterList.Length, Is.EqualTo(2));
    
                }
            }
    

    【讨论】: