2016年4月13日 星期三

NUnit gets wrong configuration file (NUnit test 讀不到 app.config)

[Problem description]
要讀取應用程式的app.config,若使用下列的 API,在 NUnit 環境下可能會讀取到錯誤的 config:

if (File.Exists(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile))
{
    // do something
}

雖然使用此 API,在執行應用程式時可以正確回傳應用程式的config 檔案 (ex: <MyAppName>.exe.config),可是在 NUnit 環境下,使用此API 卻會回傳另外的 config 檔案!
例如:
  • 使用 VS2010 + Resharper (v6.1) 會回傳 ~\UnitTest\bin\Debug 目錄下的 UnitTest.dll.config 
  • 使用 VS2015 + Resharper (v10.0) 會回傳 %temp% 目錄下某個隨機子目錄的 config 檔案
這種不確定性會造成 unit test 不夠 robust, 而且上述兩種環境都無法正確讀取到<MyAppName>.exe.config。

[Root cause]
AppDomain.CurrentDomain 可以用來取得目前應用程式的 domain 。
  1. 對於應用程式來說, AppDomain.CurrentDomain 指的是 exe 所在的目錄,一般是位於~\bin\Debug 
  2. 對於 NUnit  來說,它沒有 exe 檔案,所以指的是 UnitTest.dll 所在的目錄: ~\UnitTest\bin\Debug
  3. 然而, 使用 VS2015 + Resharper (v10.0) 卻指向 %temp% ,這個應該是設定上的問題。
既然在使用NUnit 上透過 AppDomain.CurrentDomain 只能取得 NUnit 自己的 domain ,無法取得我們想要的應用程式 domain ,因此無法透過此API 取得 <MyAppName>.exe.config

[Solution]
有下列幾種 work around:
  1). 改用應用程式的 Settings.setting 取代 <MyAppName>.exe.config
  2). 移除 app.config 與 MyAppName 的直接相依性, 改用 dependency injection 來建立 app.config 與 MyAppName的關係,如此便很方便 Mock 這個 app.config 在NUnit的程式碼當中




相關連結:
app.config 與 Settings.setting 的差異: MSDN forums, StackOverflow, User settings - MSDN
什麼是 AppDomain
AppDomain.CurrentDomain 屬性
Application 與 AppDomain.CurrentDomain 的差異

沒有留言:

張貼留言