0

我有一门课,我想为其编写单元测试。我在项目中使用 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() 听起来像是可以工作的东西,但事实并非如此。

我该如何解决这个问题?通过更改我的测试或通过实际重写被测类。

4

0 回答 0