Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.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#_.net_Unit Testing_Dependency Injection - Fatal编程技术网

C# 使用代码体中声明的具体类的单元测试类

C# 使用代码体中声明的具体类的单元测试类,c#,.net,unit-testing,dependency-injection,C#,.net,Unit Testing,Dependency Injection,很简单,我想找出的是,有没有任何方法可以干净地对这段代码进行单元测试?我可以实例化它并运行一些断言,但我指的是实际的单元测试,在这里,我会模拟服务对象来删除被测试类的任何依赖项,并让它只测试这个类,而不是它的依赖服务(在本例中为ConcreteService) 我通常的做法是在我的代码体中不创建这种类型的对象,但是如果场景无法更改,那么我可以选择什么来进行单元测试呢?如果service.Execute()是虚拟的,那么大多数模拟框架都支持这一点。我个人使用 请参阅其中详细介绍了在非接口上使用模拟

很简单,我想找出的是,有没有任何方法可以干净地对这段代码进行单元测试?我可以实例化它并运行一些断言,但我指的是实际的单元测试,在这里,我会模拟服务对象来删除被测试类的任何依赖项,并让它只测试这个类,而不是它的依赖服务(在本例中为ConcreteService)

我通常的做法是在我的代码体中不创建这种类型的对象,但是如果场景无法更改,那么我可以选择什么来进行单元测试呢?

如果service.Execute()是虚拟的,那么大多数模拟框架都支持这一点。我个人使用

请参阅其中详细介绍了在非接口上使用模拟框架的功能,并讨论了模拟框架拦截虚拟调用的功能

如果它不是虚拟的,并且您无法更改它,那么您可以使用。上面提到的帖子还提到了使用TypeMock的能力,我个人还没有使用过

微软研究网站上关于鼹鼠的描述:

Moles是一个轻量级的框架,用于.NET中基于委托的测试存根和迂回。Moles可用于绕过任何.NET方法,包括密封类型中的非虚拟/静态方法

如果service.Execute()是虚拟的,那么大多数模拟框架都支持这一点。我个人使用

请参阅其中详细介绍了在非接口上使用模拟框架的功能,并讨论了模拟框架拦截虚拟调用的功能

如果它不是虚拟的,并且您无法更改它,那么您可以使用。上面提到的帖子还提到了使用TypeMock的能力,我个人还没有使用过

微软研究网站上关于鼹鼠的描述:

Moles是一个轻量级的框架,用于.NET中基于委托的测试存根和迂回。Moles可用于绕过任何.NET方法,包括密封类型中的非虚拟/静态方法


我知道您提到过,这是一个您无法改变的情况示例,但我会努力重构该类,以便将ConcreteService作为依赖项注入。重构是一种简单得多的解决糟糕设计的方法。从你发布的内容来看,我看不出你有什么理由不能这样做


编辑:FWIW,我同意@Gishu。如果您绝对不能修改该类,例如,您不拥有该类,并且您没有修改该类的能力,那么集成测试是最好的方法。然而,如果你能看到代码和它在做什么,我支持我前面所说的,你没有理由不重构。

我知道你提到过,这是一个你无法改变的情况的例子,但我会努力重构类,以便将ConcreteService作为依赖项注入。重构是一种简单得多的解决糟糕设计的方法。从你发布的内容来看,我看不出你有什么理由不能这样做

编辑:FWIW,我同意@Gishu。如果您绝对不能修改该类,例如,您不拥有该类,并且您没有修改该类的能力,那么集成测试是最好的方法。然而,如果你能看到代码和它在做什么,我支持我前面所说的,你真的没有理由不重构。

考虑到约束条件(你不能修改/重新编译代码),恐怕除了“集成测试”it之外,你能做的不多——真正的依赖,缓慢的测试

在方法中实例化依赖项,而不是将其接受为一个构造函数或方法参数,这会使事情变得困难

正如伊桑所说,有痣(但对我个人来说,这似乎并不正确)。我更喜欢设计变更,而不是帮助我掩盖设计问题的框架。

考虑到约束条件(即您不能修改/重新编译代码),恐怕除了“集成测试”it之外,您没有什么可以做的-真正的依赖性,缓慢的测试

在方法中实例化依赖项,而不是将其接受为一个构造函数或方法参数,这会使事情变得困难


正如伊桑所说,有痣(但对我个人来说,这似乎并不正确)。我更喜欢设计变更,而不是帮助我掩盖设计问题的框架。

在这种情况下,您会如何模拟concreteservice?请记住,concreteclass是在被测试的类中实例化的。我的理解是,模拟框架无法处理这种情况,但我可能错了……我不明白,仅仅通过使execute虚拟化,您将如何模拟concreteclass。我知道在模拟conrete类时必须使成员虚拟,就像我以前在Rhinomock中所做的那样,但我不清楚在代码中安装被测试的类时,如何向该类提供模拟的conrete类。谢谢你的输入@AaronHS-模拟框架可以拦截虚拟调用。在这种情况下,您仍在实例化
ConcreteService
,但对
Execute
的调用被拦截。在这种情况下,您将如何模拟ConcreteService?请记住,concreteclass是在被测试的类中实例化的。我的理解是,模拟框架无法处理这种情况,但我可能错了……我不明白,仅仅通过使execute虚拟化,您将如何模拟concreteclass。我知道在模拟conrete类时必须使成员虚拟,就像我以前在Rhinomock中所做的那样,但我不清楚在代码中安装被测试的类时,如何向该类提供模拟的conrete类。谢谢你的输入@AaronHS-模拟框架可以拦截虚拟调用。在本例中,您仍在实例化
ConcreteService
,但对
Execute
的调用是
public class Foo{

    public SomeResult DoSomething(){
        var service = new ConcreteService();
        var foo = service.Execute();
        return foo;
    }

}