简体   繁体   English

单元测试DbProviderFactory的最佳方法

[英]Best way to unit test DbProviderFactory

I am trying to create Unit Test (NUnit) for the old code that we have. 我正在尝试为我们拥有的旧代码创建单元测试(NUnit)。

We using DbProviderFactory to check if table exist in the database before doing anything with that table. 我们使用DbProviderFactory来检查表是否存在于数据库中,然后再对该表执行任何操作。

I know that this might look more like integration testing, but regardless of what you call it I need to have a test for it. 我知道这看起来更像是集成测试,但是无论您如何称呼它,我都需要对其进行测试。 I would prefer to use something self contained and not dependent on the database. 我宁愿使用自包含的东西,也不依赖数据库。

I tried to use excel as my data source but to select table in excel it should have $ after the table name which wouldn't work in my case because I don't want to modify my code to accommodate Unit Test. 我试图使用excel作为数据源,但是要在excel中选择表,它应该在表名后有$,这在我的情况下不起作用,因为我不想修改代码以适应单元测试。

How can I unit test following code? 如何对以下代码进行单元测试?

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

Any help would be appreciated. 任何帮助,将不胜感激。

You can try using Stubs once. 您可以尝试一次使用存根。 I have written a simple test case using Stub. 我已经使用Stub编写了一个简单的测试用例。 It's working as expected. 它按预期工作。 Here is the code: 这是代码:

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


You can play around with the GetFakeReader() method to Unit Test various scenarios. 您可以使用GetFakeReader()方法进行各种场景的单元测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM