模拟静态单例?我有一些课程,我被要求使用RhinoMocks添加一些单元测试并有一些问题。首先,我知道RhinoMocks不允许模拟静态成员。我正在寻找我的选择(除了使用TypeMock)。我有一个类的示例如下所示:classExample1:ISomeInterface{privatestaticISomeInterface_instance;privateExample1(){//通过私有静态方法设置属性}staticExample1(){_instance=newExample1();}publicstaticISomeInterfaceInstance(){get{return_instance;}}//实例属性//表示遵循类似模式的对象的其他实例属性。所以当我调用上面的类时,它看起来像这样......Instance.SomeObject.GoDownARabbitHole();在这种情况下,有没有办法模拟SomeObject.GoDownARabbitHole()或模拟实例?单例与可测试性不一致,因为它们很难改变。最好使用依赖注入将ISomeInterface实例注入消费类:publicclassMyClass{privatereadonlyISomeInterfacedependency;publicMyClass(ISomeInterfacedependency){if(dependency==null){thrownewArgumentNullException("dependency");}这个.dependency=依赖;}//在其他成员中使用this.dependency}请注意GuardClaus如何与readonly关键字一起确保ISomeInterface实例始终可用。这将允许您使用RhinoMocks或其他动态模拟库将ISomeInterface的测试替身注入到消费类中。被这样的线索吓坏了,我花了很长时间才注意到单身人士并没有那么难笑。毕竟我们为什么要使用C#?只需使用反射。使用提供的示例代码,您需要确保在将静态字段设置为模拟对象之前调用静态构造函数。否则它可能会覆盖您的模拟对象。在设置测试之前调用任何对单例不起作用的东西。ISomeInterface未使用=Singleton.Instance();System.Reflection.FieldInfo实例=typeof(Example1).GetField("_instance",System.Reflection.BindingFlags.Static|System.Reflection.BindingFlags.NonPublic);模拟mockSingleton=newMock();instance.SetValue(null,mockSingleton.Object);我提供了使用Moq进行模拟的代码,但我猜RhinoMocks非常相似。这是一种使用可在初始设置并在运行时更改的委托的低接触方法。通过示例更好地解释(具体来说,模拟DateTime.Now):http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/11/09/systemtime-versus-isystemclock-dependencies-revisited.aspx书中的示例:EffectivelyUsingLegacyCode要在测试工具中运行包含单例的代码,我们必须放宽单例属性。我们是这样做的。第一步是向Singleton类添加一个新的静态方法。这个方法允许我们替换单例中的静态实例。我们称它为setTestingInstance。公共类PermitRepository{私有静态PermitRepository实例=null;privatePermitRepository(){}publicstaticvoidsetTestingInstance(PermitRepositorynewInstance){instance=newInstance;}publicstaticPermitRepositorygetInstance(){if(instance==null)newinstance();}返回实例;}publicPermitfindAssociatedPermit(PermitNoticenotice){...}...}现在我们有了setter,我们可以创建PermitRepository的测试实例并设置它。我们想在我们的测试设置中编写这样的代码:publicvoidsetUp(){PermitRepositoryrepository=newPermitRepository();...//在此处向存储库添加许可...PermitRepository.setTestingInstance(repository);您可以模拟接口ISomeInterface。然后,重构使用它的代码以使用依赖注入来获取对单例对象的引用。我在我的代码中多次遇到这个问题,我最喜欢这个解决方案。例如:publicclassUseTheSingleton{privateISomeInterfacemyX;publicUseTheSingleton(ISomeInterfacex){myX=x;}publicvoidSomeMethod(){myX.然后...UseTheSingletonuseIt=UseTheSingleton(Example1.Instance);请参见依赖注入。您已经开始了这个,但是对于难以测试的类(静态等),您可以使用适配器设计模式编写代码来包装这个难以测试的类。使用此适配器的接口,您可以单独测试您的代码。如需任何单元测试建议和进一步的测试问题,请查看Google测试博客,尤其是Misko的文章。示例您说您正在编写测试,所以可能为时已晚,但是您可以将静态变量重构为实例吗?或者,为什么说类应该保持静态?您不必一次修复所有用途,只需修复您正在处理的用途。将ISomeInterface字段添加到被测类并通过构造函数进行设置。如果您使用的是Resharper(您使用的是Resharper,不是吗?),那么这些东西中的大部分都是微不足道的。如果这很繁琐,您可以有多个构造函数,一个设置新的依赖字段,另一个调用第一个构造函数并将单例作为默认值。以上就是C#学习教程:如何模拟静态单例?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
