我正在研究一个大型项目,其中一个基类有数千个从它派生的类(多个开发人员正在研究它们)。预计每个类都会覆盖一组方法。我首先用一个符合可接受模式的代码模板生成了这几千个类文件。我现在正在编写单元测试,以确保开发人员没有偏离这种模式。下面是一个示例生成的类:使用反射验证代码与模板模式的关系
// Base class.
public abstract partial class BaseClass
{
protected abstract bool OnTest();
}
// Derived class. DO NOT CHANGE THE CLASS NAME!
public sealed partial class DerivedClass_00000001: BaseClass
{
/// <summary>
/// Do not modify the code template in any way.
/// Write code only in the try and finally blocks in this method.
/// </summary>
protected override void OnTest()
{
bool result = false;
ComObject com = null;
// Declare ALL value and reference type variables here. NOWHERE ELSE!
// Variables that would otherwise be narrowly scoped should also be declared here.
// Initialize all reference types to [null]. [object o;] does not conform. [object o = null;] conforms.
// Initialize all value types to their default values. [int x;] does not conform. [int x = 0;] conforms.
try
{
com = new ComObject();
// Process COM objects here.
// Do NOT return out of this function yourself!
}
finally
{
// Release all COM objects.
System.Runtime.InteropServices.Marshal.ReleaseComObject(com);
// Set all COM objects to [null].
// The base class will take care of explicit garbage collection.
com = null;
}
return (result);
}
}
在单元测试中,我已经能够验证经由反射下列:
- 类从[BaseClass的]派生并没有实现任何接口。
- 类名符合模式。
- catch块没有被过滤。
- 没有添加其他的catch块。
- 没有声明任何级别的字段或属性。
- 所有方法值类型变量在声明时都被手动初始化。
- 没有其他方法添加到派生类。
以上是很容易通过反射来实现,但我主张用下面的列表中挣扎:
- catch块重新抛出捕获的异常,而不是包装,或抛出一些其他异常。
- 末尾的
[return (result);]
行尚未修改,并且未添加任何其他[return (whatever);]
调用。不知道如何实现这一点。 - 验证所有实现IDisposable的引用类型已经处理完毕。
- 确认在[finally]块中已经手动取消参考[System .__ ComObject]类型的所有参考类型并将其设置为[null]。
我曾经想过解析源代码,但除非绝对必要,否则我不喜欢这种解决方案。这是混乱的,除非我有表达树,几乎不可能保证成功。
任何提示将不胜感激。
只是一个想法:如果方法*需要*被覆盖,为什么他们是'虚拟'而不是'抽象'? – 2013-05-13 14:16:31
更正了它。自从我在SO编辑器中写一个例子以来,我就错了。 – 2013-05-13 14:40:27