我正在研究一個大型項目,其中一個基類有數千個從它派生的類(多個開發人員正在研究它們)。預計每個類都會覆蓋一組方法。我首先用一個符合可接受模式的代碼模板生成了這幾千個類文件。我現在正在編寫單元測試,以確保開發人員沒有偏離這種模式。下面是一個示例生成的類:使用反射驗證代碼與模板模式的關係
// 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