我正在尝试测试一个动态实例化对象并将它们存储在集合中的类。因为我需要测试实例化它们的逻辑以及对这些对象的操作,所以我认为创建一个可以注入进行测试的辅助假工厂类是个好主意。这是我想出来的
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框架中是否有其他实现或可能已经处理这种情况的东西?
答案 0 :(得分:2)
听起来你的类是动态地实例化对象(可能在一些逻辑结构中像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所以不会尝试使用某些代码,但是使用这种模式可以最大限度地减少类对动态实例化逻辑的了解,同时还提供了挂钩动态对象模拟的地方。另外删除任何测试代码的知识。