Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将委托人用作“代理”;工厂法“;用于C中的单元测试# 问题_C#_.net_Unit Testing_Factory Method - Fatal编程技术网

C# 将委托人用作“代理”;工厂法“;用于C中的单元测试# 问题

C# 将委托人用作“代理”;工厂法“;用于C中的单元测试# 问题,c#,.net,unit-testing,factory-method,C#,.net,Unit Testing,Factory Method,让我们“画”一幅形势图: 我有一个SUT。(拥有一件好事:P) 我可以在SUT上注入一些依赖项 在一个方法中,我做了一个:new OtherClass(参数从Dependencies获得) 我想在我的SUT中对该方法进行单元测试,而不必处理创建模拟对象的复杂性,这对于其他类正确工作是有意义的。这意味着要测试其他类 我的解决方案是使用委托的工厂方法: public Func<OtherClass,Param1Type> GetOtherClass = (param1

让我们“画”一幅形势图:

  • 我有一个SUT。(拥有一件好事:P)
  • 我可以在SUT上注入一些依赖项
  • 在一个方法中,我做了一个:new OtherClass(参数从Dependencies获得)
  • 我想在我的SUT中对该方法进行单元测试,而不必处理创建模拟对象的复杂性,这对于其他类正确工作是有意义的。这意味着要测试其他类
我的解决方案是使用委托的工厂方法:

public Func<OtherClass,Param1Type> GetOtherClass = 
       (param1) => new OtherClass(param1);
public Func GetOtherClass=
(param1)=>新的其他类(param1);
坏消息:这是公开的。您可以将其视为一个可选的依赖项,如果需要,可以覆盖它。但不管怎样,公众的气味

好处:我不需要创建一个MyTestSUT来重写这个方法,甚至不需要在SUT上使用mock来重写这个方法

问题:
有没有更好的解决办法?这是正确的吗?

为什么要将其作为公共字段?听起来它基本上是一种依赖关系,就像任何其他依赖关系一样:当你给它一些其他值时,你想要一些能为你提供
OtherClass
的东西。为什么不像其他依赖项一样将其作为构造函数参数(或者以其他依赖项注入方式)

如果愿意,您总是可以提供一个没有此参数的构造函数重载,该参数将委托给较长的构造函数。这就是我通常提供“默认”依赖项实现的方式


换句话说:这在逻辑上与(比如)一个
iaauthenticator
接口有何不同?当提供用户名和密码时,该接口将返回一个
用户配置文件
?您碰巧使用委托作为避免声明接口的捷径,但在我看来这只是一个细节。您可能会发现,随着时间的推移,您实际上希望在“提供”部分(例如缓存)中添加更多的智能。

听起来您希望使用类似于它的自定义功能的东西。
这将使您能够模拟SUT中的所有或部分公共字段以及其他构造函数参数(如果需要)。

我使用autofixture。但制作对SUT依赖项“有意义”的模拟对象所需的工作就像通过SUT再次测试SUT依赖项一样。我不想做的事。好。。。我试过了,但是工作太多了,我不想创建一个带有接口的工厂类,该接口将包含一个创建我的类的方法。另外,将受保护的虚拟方法作为工厂方法的想法给了我同样的印象:代码太多。我的DI是使用公共属性(Funq)完成的。因此,这将允许我拥有一个“默认”依赖项,并能够在测试时更改它。这是一个“两难选择”:它适合我的DI系统,但这是我第一次这么做。@graffic:我的观点是,基本上你已经有了一个工厂类——委托。就好像您自己创建了该接口,但该代理具有更多的语言支持。如果你认为它是一个工厂(或转换器),那么它是一个完全合理的依赖关系。这确实帮助我消除了疑虑。