简体   繁体   English

如何使用Rhino Mocks模拟一个具有私有Constructor的类

[英]How to Mock a class which has private Constructor using Rhino Mocks

I am using Rhino Mocks 3.6 我正在使用Rhino Mocks 3.6

i have a class "Configuration.cs" which has a private constructor (i did it for the Singleton implementation). 我有一个类“Configuration.cs”,它有一个私有构造函数(我为Singleton实现做了)。 Now i want to mock this class (Partial Mock) but i am not able to do it. 现在我想模仿这个类(Partial Mock),但我无法做到。 Error: 错误:

Can not instantiate proxy of class: Efi.CrmIntegration.MonarchServices.Utilities.Configuration. 无法实例化类的代理:Efi.CrmIntegration.MonarchServices.Utilities.Configuration。 Could not find a parameterless constructor. 找不到无参数构造函数。 Parameter name: constructorArguments 参数名称:constructorArguments

Whats the solution for the same. 什么是相同的解决方案。

Static singletons are difficult to mock and to test, and should be avoided, ideally. 静态单例很难模拟和测试,理想情况下应该避免。 As RhinoMocks has pointed out, you can't make a partial mock of your Configuration singleton, but you have some options. 正如RhinoMocks指出的那样,你不能对你的配置单例进行部分模拟,但你有一些选择。

  1. Make your private constructor public. 公开您的私有构造函数。 This should be considered a quick hack, though. 不过,这应该算是一个快速的黑客行为。 There are much better ways of doing this. 有更好的方法来做到这一点。

  2. Change how your singleton is instantiated. 更改单例实例化的方式。 Give your Configuration class an interface, let's say IConfiguration . 给你的Configuration类一个接口,比如说IConfiguration You probably already have a static Instance property on Configuration . 您可能已在Configuration上拥有静态Instance属性。 Change it's type to be IConfiguration , and give it a public setter. 将其类型更改为IConfiguration ,并为其提供公共设置器。 In your unit tests, mock or stub IConfiguration , and set the Configuration.Instance property to that. 在单元测试中,模拟或存根IConfiguration ,并将Configuration.Instance属性设置为该属性。 This is still something of a hack (but it is useful when you have lots of classes that are already using the singleton, and you don't have time to implement the next option). 这仍然是一种破解(但是当你有很多已经在使用单例的类时,它很有用,而你没有时间实现下一个选项)。

  3. Use dependency injection. 使用依赖注入。 Give your Configuration class an interface, again let's say IConfiguration . 给你的Configuration类一个接口,再说一次IConfiguration Classes that have a dependency on the Configuration singleton should be changed to take an IConfiguration parameter in their constructor. 应更改依赖于Configuration单例的类,以在其构造函数中获取IConfiguration参数。 When you create an instance of one of these classes, you inject in the singleton instance of Configuration . 当您创建其中一个类的实例时,您将注入Configuration的单例实例。 When testing, make a mock or stub of type IConfiguration , and pass that to the classes instead. 在测试时,制作IConfiguration类型的模拟或存根,并将其传递给类。 You can improve on this with a dependency injection framework, like Castle Windsor or Ninject, which you could probably use to do away with your need for a static singleton altogether. 您可以使用依赖注入框架(例如Castle Windsor或Ninject)来改进这一点,您可以使用它来完全取消对静态单例的需求。

I highly recommend you change your design and use option 3 (with a dependency injection framework, if possible). 我强烈建议您更改设计并使用选项3(如果可能,使用依赖注入框架)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM