単体テストを書きたいクラスがあります。プロジェクトで StructureMap (2.6.3) を使用していますが、いくつか問題があります。
テストには、Nunit (2.6.0.12054) と RhinoMocks (3.6) を使用します。
通常、クラスのコンストラクターに依存関係を挿入すると、単体テストで依存関係をモックに簡単に置き換えることができます。しかし、テスト対象のクラスがいつ作成されるかを制御できない場合がいくつかあります。このような場合、ObjectFactory.GetInstance() を使用して依存関係を取得します。
public class MyClass
{
public int MyMethod(string parameter)
{
var myDependency = ObjectFactory.GetInstance<IMyDependency>();
try
{
return myDependency.CalculateValue(parameter);
}
catch (Exception ex)
{
//Suppress exception.
return 0;
}
}
}
このクラスとメソッドのために、2 つのテストを書きたいと思います。最初に、依存関係が呼び出され、計算された値がテスト対象のクラスによって返されることをテストしたいと思います。次に、依存関係が例外をスローする可能性があり、この例外がテスト対象のクラスによって抑制され、その場合はゼロを返すことをテストしたいと考えています。
[TestFixture]
public class MyClassTests()
{
[Test]
public void MyMethod_DependencyReturnsValue_ReturnsValueFromDependency
{
//Arrange.
const int valueFromDependencyStub = 333;
var myDependencyStub = MockRepository.GenerateStub<IMyDependency>();
myDependencyStub.Stub(x => x.CalculateValue()).Return(valueFromDependencyStub);
ObjectFactory.Inject<IMyDependency>(myDependencyStub);
var target = new MyClass();
//Act.
var result = target.MyMethod("test");
//Assert.
Assert.AreEqual(valueFromDependencyStub, result);
}
[Test]
public void MyMethod_DependencyThrowsException_ReturnsZero
{
//Arrange.
var myDependencyStub = MockRepository.GenerateStub<IMyDependency>();
myDependencyStub.Stub(x => x.CalculateValue()).Throw(new Exception());
ObjectFactory.Inject<IMyDependency>(myDependencyStub);
var target = new MyClass();
//Act.
var result = target.MyMethod("test");
//Assert.
Assert.AreEqual(0, result);
}
}
これらのテストは両方とも、個別に実行すると機能しますが、両方を実行すると機能しません。私の実際のケースでは、スタブ化された依存関係が例外をスローする 2 番目のテストが最初に実行されます。他のテストが実行されると、スタブ化された依存関係は引き続き例外をスローします。
問題は、私が理解しているように、グローバルな ObjectFactory を使用していて、それにスタブを挿入していることです。各テストの後に ObjectFactory をクリアできればおそらくうまくいくでしょうが、それを行う方法が見つかりませんでした。ObjectFactory.EjectAllInstancesOf() は機能するもののように聞こえましたが、機能しません。
これを解決するにはどうすればよいですか?テストを変更するか、テスト対象のクラスを実際に書き直すことによって。