我有一门课,我想为其编写单元测试。我在项目中使用 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;
}
}
}
对于这个类和方法,我想编写两个测试。首先,我想测试是否调用了依赖项,并且它计算的值由被测类返回。其次,依赖项可能会引发异常,我想测试这个异常是否被被测类抑制,并且在这种情况下它返回零。
[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);
}
}
如果我单独运行它们,这两个测试都可以工作,但如果我同时运行它们,它就不起作用。我的真实案例是第二个测试,其中存根依赖项引发异常,首先运行。当另一个测试运行时,存根依赖项仍然会引发异常。
据我了解,问题在于我正在使用全局 ObjectFactory 并将我的存根注入其中。如果我可以在每次测试后清除 ObjectFactory,那可能会起作用,但我发现没有办法做到这一点。ObjectFactory.EjectAllInstancesOf() 听起来像是可以工作的东西,但事实并非如此。
我该如何解决这个问题?通过更改我的测试或通过实际重写被测类。