2011-06-08 114 views
1

我试图测试一个类动态实例化对象并将它们存储在集合中。因为我需要测试实例化它们的逻辑和对这些对象的操作,所以我认为创建一个可以注入测试的辅助假工厂类是一个好主意。以下是我想出了注入犀牛嘲笑“假”工厂

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属性中的实例化假对象来检查它们的状态。在Rhino Mocks框架中是否还有其他实现或可能存在的某些内容已经处理了这种情况?

+1

你可以显示你使用这个FakeFactory的代码吗?你所做的是一个坏主意 - 正如你所说的,在你的主项目中测试代码是一种很大的味道。被测试的代码是否需要某种工厂,并且正在尝试用FakeFactory替代?难道你不能简单地为该工厂创建一个接口,然后由RhinoMocks嘲笑,根据需要提供适当的(模拟)类? – 2011-06-08 19:59:31

+0

我想过创建一个接口,并用一个工厂来替换简单的实例化,这个工厂实现了接口并返回被测试的类的新对象以供使用。考虑到工厂里没有任何逻辑,它只会用于补偿测试目的,所以我认为这也是不好的做法。我认为你提供的是合理的建议。你也应该提供它作为答案。 – jlafay 2011-06-08 20:18:20

回答

2

这听起来像你的类是动态实例化对象(可能在一些像switch语句的逻辑结构?),你想允许与你的FakeFactory测试这个?

使用FakeFactory并让您的类测试知道测试代码是一个很大的代码味道,表明过度紧密的耦合以及为您的类引入一个不必要的关注(事实上,动态实例已经是一个不必要的问题) 。

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

,以便类最终会看起来像这样:

public class ClassBeingTested 
{ 
    private IFactory _yourFactory; 

    public ClassBeingTested(IFactory yourFactory) 
    { 
     _yourFactory = yourFactory; 
    } 

    public MethodWithDynamicInstantiation() 
    { 
     IClass = _yourFactory.GetClassDynamically(someparam); 
    } 
} 

我没有用RhinoMocks在年内所以不会尝试一些代码,但这种模式您减少类有关于知识动态实例化逻辑,同时还提供了在动态对象的模拟中挂钩的位置,并且除去了对测试代码的任何知识。