2011-03-22 54 views
12

.NET中是否有可能在子進程中執行方法(委託,靜態方法等)? System.Diagnostics.Process似乎需要一個實際的文件名,這意味着需要一個單獨的可執行文件。開始一個執行委託的新進程

我想要做的是在單元測試中驗證在進程退出時清理了OS資源。我知道,可能使用CodeDOM或IL代來創建這樣一個程序集並執行它,但單元測試的重點是隔離組件部分,而不是創建複雜性。出於同樣的原因,我想避免一個單獨的程序集。

理想情況下,我會做這樣的事情:

public static void CreateCounter() 
{ 
    var counter = new PerformanceCounter("category", "counter", "instance"); 
    counter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process; 
} 

[Test] 
public void TestResourceDisposal() 
{ 
    // Start child process to execute CreateCounter() 
    ... 
    // verify the resource is disposed 
} 

回答

6

首先,沒有,有沒有辦法做到這一點。我的過程意味着一個.exe。這不是Unix,你可以派生一個父進程副本。

我只是創建一個微小的.exe來運行。你需要用不同的性能計數器來運行測試嗎?如果它與一個人一起工作,那麼它肯定會與他們中的任何人一起工作?

+0

所以看起來你是正確的 - 我沒有找到可以做到的管理方式。我已經使用了CodeDOM路徑,並且正在生成微型的.exe。謝謝! – Ben 2011-03-22 23:48:47

0

我不確定你想要完成什麼,但是從CreateCounter返回性能計數器實例並使用using指令會更容易,因爲PerformanceCounter是IDisposable。像這樣:

using (var counter = CreateCounter()) 
{ 
    // Do some work 
} 

然後,即使在測試過程中拋出計數器,計數器也會始終清理乾淨。

否則,我想你想要的是create a new thread。然後你可以thread.Join()等待線程完成。有關更多信息,請參閱System.Threading namespace

+0

不幸的是,既不調用Dispose()也不產生線程就足夠了。我特別針對發佈(通過Windows)發佈的perf計數器實例名稱進行了測試,該名稱指定僅在進程退出時發生 - 線程連接將不具有所需的效果,並且Dispose()也不會發生。 – Ben 2011-03-22 05:24:04

2

你在說什麼不是單元測試。與實際(昂貴的)操作系統服務交互違反了單元測試旨在爭取的隔離基本原則。

如果您的目的是測試在更多的終端到終端的時尚代碼,與性能計數器等實際互動,這將是一個集成測試,應該在一個更「重型寫「的方式,即根據需要編寫單獨的EXE,運行任何複雜的設置或清理步驟等。

如果您需要對處理性能計數器的組件進行單元測試,則必須首先將此依賴關係抽象出來。通常,您將創建一個表示性能計數器表面區域的基類或接口,然後創建某種類型的test double以在(測試)運行時替換其功能。真正的系統將使用一個簡單的包裝器,委託給實際的性能計數器,並將通過上面的集成測試來執行。

從閱讀你上面的評論,它幾乎聽起來像你試圖測試.NET框架的保證。我會質疑這是否真的有必要,因爲它已經很好地測試過了,雖然也許你想測試你的代碼是否正確使用它(在這種情況下,你可以根據你正在尋找的驗證來進行單元測試或集成測試)。

+0

WRT你最後一段:是和否。我實際上在櫃檯周圍測試我們自己的包裝紙;通常一個模擬就足夠了,但在這種情況下並不多。表演櫃檯有一段歷史(以我的經驗)徘徊,並不總是按照他們應有的方式行事;測試(通過任何名稱)應該在發生時隔離這種行爲。 – Ben 2011-03-22 18:35:44