背景:MSTESTを使って単体テストを実行しようとしたところ、テスト対象のクラスでエラー。該当の箇所は設定ファイル(.config)を呼び出したコードだった。
単体テストはテスト対象のクラスで右クリック>「単体テストを作成」で作成したMSTESTプロジェクト。
MSTESTプロジェクトでApp.configを置いていたものの、エラーが発生した。
//ここでエラー 'System.NullReferenceException:
//Object reference not set to an instance of an object.'
ret = ConfigurationManager.AppSettings["キー名"].ToString();
原因:ではどの設定ファイルを呼んでいるか、ということを次のコードで発見した。
var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
このconfigFileという、インスタンスのFilePath変数に読み込んでいるconfigファイルが記載されていた。私の場合はテストプロジェクトのbinの中にある(ことになっている)testhost.x86.dll.configだった。
だが、ConfigurationManager.AppSettings["キー名"] での取得はConfig\machine.configという値になっていて不明なファイルを取得していた。
testhost.x86はテストユニットをx86で実行した際に作成されるものだそう。つまりプラットフォームがAny CPUで実行したときのような挙動をしていなかったため、App.configは読み込まれていなかったようだ。
対処法① 置き換え
最も安易な対処法としてはそのconfigファイルを作ってApp.configの内容をそのままコピペすることだろう。
対処法② コード上で修正
以下のコードを書くことで読み込むconfigファイルを指定できる。
var configFile = @"Hoge.config";
var exeFileMap = new ExeConfigurationFileMap { ExeConfigFilename = configFile };
var config = ConfigurationManager.OpenMappedExeConfiguration(exeFileMap, ConfigurationUserLevel.None);
(cf. https://devlights.hatenablog.com/entry/20110203/p1)
この後に
var settings = configFile.AppSettings.Settings;
settings["キー"].Value = "";
とすればキーが持つ値の書き換えもできる。
対処法③ プロジェクトファイルで指定
ややこしそうなので試していないが、プロジェクトファイルに読み込むconfigを指定すればコードなどを追加することなく指定できそう。
(cf. https://araramistudio.jimdo.com/2023/07/30/c-app-config%E3%82%92debug%E3%81%A8release%E3%81%A7%E4%BD%BF%E3%81%84%E5%88%86%E3%81%91%E3%82%8B/)
結論:今回はプラットフォームの違いで既定のconfigファイルが読み込まれていなかった模様。どのファイルを使用しているかを知るにはconfigファイルの内容だけでない、OpenMappedExeConfiguration()の使用が必要だった。