我们刚刚分离了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的方式?
答案 0 :(得分:3)
由于您的Sql2005DatabaseAdapter
可能无法与SQL 2000服务器一起使用,因此继承关系是错误的,因为它有效地说“Sql2005DatabaseAdapter
是 Sql2000DatabaseAdapter
“因此导致了各种各样的怪异,比如你目前在测试中遇到的问题。
如果你想避免这种情况,最好将大部分功能转移到抽象基类中并直接从它继承:
public abstract class SqlDatabaseAdapter : DatabaseAdapter, ISqlDatabaseAdapter
...
public class Sql2000DatabaseAdapter : SqlDatabaseAdapter
...
public class Sql2005DatabaseAdapter : SqlDatabaseAdapter
...
答案 1 :(得分:2)
我怀疑你在这里已经知道了答案,你只是不喜欢它。)
通过说Sql2005DatabaseAdapter : Sql2000DatabaseAdapter
,您说Sql2005DatabaseAdapter
的任何实例绝对是 a Sql2000DatabaseAdapter
。那么就要求Assert.IsInstanceOfType
以某种方式假装它不是......当然不会起作用。
您已经正确地给出了测试确切类型的方法 - 为什么不想使用它?
编辑我的意思是也说出类似于David Schmitt的内容 - 这种继承层次感觉错了。说Sql2005DatabaseAdapter
是一个Sql2000DatabaseAdapter
并不是真的(谈论现实世界的概念),是吗?