【问题标题】:Is there a way to mock a DB2Exception that has no public constructors?有没有办法模拟没有公共构造函数的 DB2Exception?
【发布时间】:2013-01-25 23:04:17
【问题描述】:

我正在编写单元测试,我想模拟DB2Exception 被抛出的场景。

问题在于它没有公共构造函数,所以我无法创建它,而且大多数单元测试框架(我使用带有 nunit 的 Rhino Mocks)也无法为它们创建存根。

我是否坚持无法测试这种交互?

(详情:这是IBM.Data.DB2.dll中定义的DB2Exception - 版本8.1.2.1)

【问题讨论】:

  • 你使用 NUnit 作为你的测试运行器吗?
  • @akousmata 是的,我是。已编辑:)
  • 在我意识到它没有那么有用后删除了我以前的帖子,但一种方法是使用包装类来执行您的查询。您是否正在尝试测试您的 catch 子句的行为或类似的东西?
  • 是的,正在尝试测试 catch 子句。我可以使用包装器类,但我还需要创建包装器异常,这很不幸。
  • 是的,这是我所知道的唯一方法,这是不幸的。 DB2Exception 中一定隐藏了一些东西,他们不希望您接触,否则他们不会将其密封。

标签: .net unit-testing mocking db2


【解决方案1】:

我希望DB2Exception 有一些派生类,但可惜 - 不,它是密封的。 Here's the class description.

由于 DB2Exceptions 显然是由某人抛出的,因此可能有一个 internal 构造函数。您必须借助反射才能使用它。曾经有一个 .NET Reflector 可以分析 MSIL 并生成 C# 代码,但现在它需要花钱。你可以找到一些alternatives here

【讨论】:

    【解决方案2】:

    编辑 我以前的帖子一点用都没有,这是我的第二次尝试。虽然您可能仍想在其中执行一些模拟元素,但无需查看您的代码,我不知道这种方法的哪些元素会起作用,哪些不会。无论如何,这是我在尝试测试一般捕获块或异常时采用的一种方法:

    public class A
    {
        public void ExecuteDB2Query(string query, DB2Connection connection)
        {
            try
            {
                // Code for executing the DB2 query
            }
            catch(DB2Exception ex)
            {
                // Catch block you are trying to test
            }
        }
    
        // Actual method
        public void MyMethod()
        {
            var query = "Select * FROM TableInApplication";
            var connection = new DB2Connection("DATABASE=GOODDB");
            ExecuteDB2Query(query, connection);
        }
    }
    
    [Test]
    public void MyMethod_CallsExecutDB2Query()
    {
        // Test that MyMethod is calling ExecuteDB2Query   
    }
    
    // Intentionally pass it bad data to test your catch block
    // under the notion that the code that executes in the application 
    // will be using the same method and thus the same catch block
    [Test]
    public void ExecuteDB2Query_Handles_Exception()
    {
        var queryString = "Select* FROM NonExistentTable";
        var connection = new DB2Connection("DATABASE=BADDB");
        var aClass = new A();
       Assert.Throws<DB2Exception>(() => aClass.ExecuteDB2Query(queryString, connection));
    }
    

    这不是处理这个问题的最优雅的方法,但如果你不能排除异常,那么我猜想,分解代码的职责并通过触发异常分别测试每个部分是下一个最好的事情。

    【讨论】:

    • 我曾考虑过这种方法......不幸的是,我想测试特定的错误代码(死锁/回滚),在这些代码中重试可能有效;)
    猜你喜欢
    • 2012-02-27
    • 1970-01-01
    • 2013-07-10
    • 1970-01-01
    • 2022-06-22
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多