C# 单元测试DbProviderFactory的最佳方法

C# 单元测试DbProviderFactory的最佳方法,c#,.net,unit-testing,nunit,dbproviderfactories,C#,.net,Unit Testing,Nunit,Dbproviderfactories,我正在尝试为我们已有的旧代码创建单元测试(NUnit) 我们使用DbProviderFactory检查数据库中是否存在表,然后再对该表执行任何操作 我知道这看起来更像是集成测试,但不管你怎么称呼它,我都需要对它进行测试。我更喜欢使用自包含的、不依赖于数据库的东西 我尝试使用excel作为数据源,但在excel中选择表时,表名后面应该有$,这在我的情况下不起作用,因为我不想修改代码以适应单元测试 如何对以下代码进行单元测试 static bool TableDoesNotExist(string

我正在尝试为我们已有的旧代码创建单元测试(NUnit)

我们使用DbProviderFactory检查数据库中是否存在表,然后再对该表执行任何操作

我知道这看起来更像是集成测试,但不管你怎么称呼它,我都需要对它进行测试。我更喜欢使用自包含的、不依赖于数据库的东西

我尝试使用excel作为数据源,但在excel中选择表时,表名后面应该有$,这在我的情况下不起作用,因为我不想修改代码以适应单元测试

如何对以下代码进行单元测试

static bool TableDoesNotExist(string tableName, string connectionString, string providerName = "System.Data.OleDb")
    {
        try
        {
            DbProviderFactory providerFactory = DbProviderFactories.GetFactory(providerName);

            using (DbConnection conn = providerFactory.CreateConnection())
            {
                conn.ConnectionString = connectionString;
                conn.Open();

                DbCommand cmd = providerFactory.CreateCommand();
                cmd.Connection = conn;

                string tblQuery = "";

                if (providerName == "System.Data.Odbc")
                    tblQuery = string.Format("SELECT COUNT(*) FROM SYSTABLE WHERE TABLE_NAME = '{0}'", tableName);
                else
                    tblQuery = string.Format("SELECT COUNT(*) FROM [INFORMATION_SCHEMA.TABLES$] WHERE TABLE_NAME = '{0}'", tableName);

                cmd.CommandText = tblQuery;

                Console.WriteLine(cmd.CommandText);

                DbDataReader dr = cmd.ExecuteReader();

                DataTable dt = new DataTable();
                dt.Load(dr);

                if (dt.Rows.Count == 1 && Convert.ToInt32(dt.Rows[0][0]) == 0)
                {
                    return true;
                }


            }

            return false;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

        return false;
    }

任何帮助都将不胜感激

您可以尝试使用存根一次。我已经使用存根编写了一个简单的测试用例。它按预期工作。代码如下:

    [TestMethod]
    public void Test01()
    {
        using (ShimsContext.Create())
        {
            var dbConnectionOpened = false;
            var fakeConnection = new StubDbConnection()
            {
                Open01 = () => { dbConnectionOpened = true; }
            };
            var fakeCommand = new StubDbCommand()
            {
                ExecuteDbDataReaderCommandBehavior = (com) => GetFakeReader()
            };
            var fakeDbProviderFactory = new StubDbProviderFactory()
            {
                CreateConnection01 = () => fakeConnection,
                CreateCommand01 = () => fakeCommand
            };
            ShimDbProviderFactories.GetFactoryString = (arg1) => fakeDbProviderFactory;

            var val = SqlConnectionFactory.TableDoesNotExist("testTable", "conn");
            Assert.IsTrue(dbConnectionOpened);
            Assert.IsTrue(val);
        }            
    }

    private DbDataReader GetFakeReader()
    {
        const int count = 0;
        var dt = new DataTable("Test-Table");
        dt.Columns.Add(new DataColumn("Count"));
        dt.Rows.Add(count);
        return dt.CreateDataReader();
    }


您可以使用GetFakeReader()方法对各种场景进行单元测试。

您可以使用垫片对DbFactory进行单元测试。这是一段非常古老的代码,它使用.NET 2.0,但不确定垫片是否有效。还有其他想法吗?