单元测试异常处理

时间:2012-05-16 09:33:27

标签: c# unit-testing

这里看似简单的一个。如何使用单元测试来测试此代码块的异常处理?

    public DbFactoryResponseType Close()
    {
        DbFactoryResponseType dbFactoryResponse = new DbFactoryResponseType();
        try
        {
            if (m_isConnected)
            {
                m_isConnected = false;

                if (m_hasRecordSet)
                {
                    m_hasRecordSet = false;

                    m_dbFactoryDatabaseDataReader.Close();
                    m_dbFactoryDatabaseDataReader.Dispose();
                }

                m_dbFactoryDatabaseCommand.Dispose();
                m_dbFactoryDatabaseConnection.Close();
                m_dbFactoryDatabaseConnection.Dispose();

            }

            dbFactoryResponse.ExceptionMessage = "";
            dbFactoryResponse.Success = true;
            dbFactoryResponse.UserFriendlyMessage = "OK";

            return dbFactoryResponse;
        }
        catch (Exception ex)
        {
            dbFactoryResponse.ExceptionMessage = ex.Message;
            dbFactoryResponse.Success = false;
            dbFactoryResponse.UserFriendlyMessage = "Error: Error while attempting to close the database connection.";

            return dbFactoryResponse;
        }
    }

这是我到目前为止所做的,但我不知道如何使异常激活允许我测试输出。

    /// <summary>
    /// Test method to test closing a PosgreSQL database connection.
    /// </summary>
    [TestMethod]
    public void TestClosePostgreSQLConnectionException()
    {
        const string connectionString = "Server=myIp;Port=myPort;Database=myDatabase;User Id=myUser;Password=myPassword;";

        const string provider = "Npgsql";

        DbProviderFactoryConnection aDbProviderFactoryConnection = new DbProviderFactoryConnection(connectionString, provider);

        DbFactoryResponseType dbFactoryResponseType = aDbProviderFactoryConnection.Close();

        Assert.IsNotNull(dbFactoryResponseType);

        Assert.AreEqual(false, dbFactoryResponseType.Success);
    }  

1 个答案:

答案 0 :(得分:4)

您可以创建IDbFactoryDatabaseConnection的模拟版本(这是您需要介绍的接口),然后在模拟的设置中,在模拟上调用Close()时抛出异常并且然后在测试中检查ExceptionMessageSuccessUserFriendlyMessage

你这样做的方法是使用像Rhino Mocks或MoQ这样的模拟框架,或者你甚至可以创建自己的模拟或存根。然后,您将在测试中将类的模拟版本注入到类构造函数中(假设您使用构造函数注入而不是setter注入),然后您将能够控制模拟的行为。

使用MoQ,如何执行此操作的示例如下:

Mock<IDbFactoryDatabaseConnection> connectionMock = new Mock<IDbFactoryDatabaseConnection>();

DbProviderFactoryConnection aDbProviderFactoryConnection = new DbProviderFactoryConnection(connectionString, provider, connectionMock.Object);

connectionMock.Setup(c => c.Close()).Throws<Exception>();

DbFactoryResponseType dbFactoryResponseType = aDbProviderFactoryConnection.Close();

当然,根据行业最佳实践,这也意味着您必须遵守SOLID原则,特别是依赖性倒置原则,这意味着您需要为DbFactoryDatabaseConnection类创建一个接口(我假设这是你的班级名称),这就是我在上面的例子中所展示的。