注射Rhino Mocks”;假的“;工厂

本文关键字:假的 工厂 Rhino Mocks 注射 | 更新日期: 2023-09-27 17:58:37

我正在尝试测试一个动态实例化对象并将其存储在集合中的类。因为我需要测试实例化它们的逻辑以及对这些对象的操作,所以我认为创建一个可以注入测试的辅助伪工厂类是一个好主意。以下是我提出的

public class RhinoFakeFactory<TFakeable> where TFakeable : class
{
    public List<TFakeable> Fakes { get; set; }
    public FakeType FakeTypeToCreate { get; set; }
    public TFakeable GetFake()
    {
        TFakeable fake = default(TFakeable);
        switch (FakeTypeToCreate)
        {
            case FakeType.None:
            case FakeType.Stub:
                fake = MockRepository.GenerateStub<TFakeable>();
                break;
            case FakeType.DynamicMock:
                fake = MockRepository.GenerateMock<TFakeable>();
                break;
            case FakeType.DynamicMockWithRemoting:
                fake = MockRepository.GenerateDynamicMockWithRemoting<TFakeable>();
                break;
            case FakeType.StrickMock:
                fake = MockRepository.GenerateStrictMock<TFakeable>();
                break;
            case FakeType.StrickMockWithRemoting:
                fake = MockRepository.GenerateStrictMockWithRemoting<TFakeable>();
                break;
            case FakeType.PartialMock:
                fake = MockRepository.GeneratePartialMock<TFakeable>();
                break;
        }
        Fakes.Add(fake);
        return fake;
    }
    public RhinoFakeFactory()
    {
        Fakes = new List<TFakeable>();
    }
}
public enum FakeType
{
    None,
    Stub,
    DynamicMock,
    DynamicMockWithRemoting,
    StrickMock,
    StrickMockWithRemoting,
    PartialMock
}

写完之后,我想"我可以很好地注入它,但现在我必须引用我的测试项目和名称空间"。这对我来说不太好。也许是因为我是单元测试的新手,并且尽可能地遵守惯例。据我所知,测试代码对被测试的代码应该是透明的,这样就可以尽可能多地关注和清楚地了解它试图实现的目标。

我应该停止担心,使用我的假工厂吗?我之所以这么做,是因为它生成了fakes,因为我在上面描述的实例中需要它们,而且我可以访问fakes属性中的实例化的fake对象来检查它们的状态。Rhino Mocks框架中是否已经实现了其他东西,或者可能已经处理了这种情况?

注射Rhino Mocks”;假的“;工厂

听起来你的类正在动态实例化对象(可能是在一些逻辑结构中,比如switch语句?),你想允许用你的FakeFactory进行测试吗?

使用FakeFactory并让测试中的类了解测试代码是一种很大的代码气味,这表明耦合过于紧密,并给类带来了不必要的担忧(事实上,动态实例化已经是一个不必要的问题)。

你应该做的是引入工厂模式作为你获得动态对象的方式,并在你的工厂上有一个接口,允许你使用RhinoMocks来替换它。然后,当您配置Mock对象时,您可以告诉工厂根据需要返回另一个Mock。

所以你的课最终会变成这样:

public class ClassBeingTested
{
    private IFactory _yourFactory;
    public ClassBeingTested(IFactory yourFactory)
    {
        _yourFactory = yourFactory;
    }
    public MethodWithDynamicInstantiation()
    {
        IClass = _yourFactory.GetClassDynamically(someparam);
    }
}

我已经好几年没有使用RhinoMocks了,所以不会尝试一些代码,但使用这种模式,您可以最大限度地减少类对动态实例化逻辑的了解,同时还可以提供挂接动态对象的mock的位置,并额外删除任何测试代码的知识。