【问题标题】:How to exclude ancestors when calling Assert.IsInstanceOfType?调用 Assert.IsInstanceOfType 时如何排除祖先?
【发布时间】:2009-06-15 07:30:26
【问题描述】:

我们刚刚分离了 SQL Server 数据库适配器以允许 SQL Server 2000 和 2005 之间的差异,特别是 nvarchar(max) 数据类型。

由于代码更改非常小,我没有重新实现我们的适配器接口和抽象基类,而是从 SQL 2000 继承了 SQL 2005 适配器并覆盖了适当的方法和属性。

public abstract class SqlDatabaseAdapter : DatabaseAdapter, ISqlDatabaseAdapter
...
public class Sql2000DatabaseAdapter : SqlDatabaseAdapter
...
public class Sql2005DatabaseAdapter : Sql2000DatabaseAdapter
...

我们的单元测试代码以前只是强制转换为特定类型的适配器,然后针对该类型进行断言,但现在我们有一个适配器工厂方法来构建适当的 SQL Server 适配器(通过配置或通过 SQL 连接找到) ,我想验证确切的类型是否已实例化(因为我们现在默认使用 SQL Server 2005),唯一的问题是我们的旧测试在它们应该失败时通过了 :)

在下面的例子中,实体工厂创建了一个Sql2005DatabaseAdapter,但是测试通过了,因为这个类型继承自Sql2000DatabaseAdapter。而且它还可以在祖先链的上游发挥作用。

Entity foo = EntityFactory.Create("foo"); 
Assert.IsInstanceOfType(typeof(SqlDatabaseAdapter), foo.Adapter); // Should fail for test
Assert.IsInstanceOfType(typeof(Sql2000DatabaseAdapter), foo.Adapter); // Should fail for test
Assert.IsInstanceOfType(typeof(Sql2005DatabaseAdapter), foo.Adapter); // Should pass

我明白它为什么会通过,我可以使用一般的 Assert.AreEqual 方法来修复这个特殊情况。

Assert.AreEqual(typeof(Sql2005DatabaseAdapter), foo.Adapter.GetType());

但我很好奇是否有使用 Assert.IsInstanceOfType 的方法?

【问题讨论】:

    标签: c# .net unit-testing nunit


    【解决方案1】:

    由于您的Sql2005DatabaseAdapter 可能无法与 SQL 2000 服务器一起使用,因此继承关系是错误的,因为它实际上表示“Sql2005DatabaseAdapter 是一个 Sql2000DatabaseAdapter”,从而导致所有各种奇怪的东西,比如你目前在测试中遇到的问题。

    如果您想避免这种情况,最好将大部分功能移入抽象基类并直接从该基类继承:

    public abstract class SqlDatabaseAdapter : DatabaseAdapter, ISqlDatabaseAdapter
    ...
    public class Sql2000DatabaseAdapter : SqlDatabaseAdapter
    ...
    public class Sql2005DatabaseAdapter : SqlDatabaseAdapter
    ...
    

    【讨论】:

    • 当然!谢谢大卫,我想我开始编码太快了,没有花足够的时间思考这些关系。
    【解决方案2】:

    我怀疑你已经知道这里的答案,只是你不喜欢它:)

    Sql2005DatabaseAdapter : Sql2000DatabaseAdapter,就是说Sql2005DatabaseAdapter 的任何实例绝对是Sql2000DatabaseAdapter。所以然后问Assert.IsInstanceOfType 以某种方式假装它不是......肯定不会起作用。

    您已经正确地给出了一种测试确切类型的方法 - 为什么不想使用它?

    edit 我的意思也是说类似于 David Schmitt 所说的话 - 这种继承层次结构感觉不对。说Sql2005DatabaseAdapter IS Sql2000DatabaseAdapter 不是真的(谈论现实世界的概念),是吗?

    【讨论】:

    • 所以我不会再遇到这个问题了 :) 说真的,只是因为我们没有工厂方法并且正在针对特定类型进行强制转换,我才发现我们的测试有问题(因为我正在重构特定的类型转换)。
    猜你喜欢
    • 2011-01-28
    • 2020-07-17
    • 2022-07-25
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 1970-01-01
    相关资源
    最近更新 更多