Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.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_Nunit_Private Methods - Fatal编程技术网

C# 使用线程、事件和私有方法测试类 普遍共识

C# 使用线程、事件和私有方法测试类 普遍共识,c#,.net,unit-testing,nunit,private-methods,C#,.net,Unit Testing,Nunit,Private Methods,关于测试复杂类和私有方法的主题,我已经读了很多书 普遍的共识似乎是: “如果您需要测试私有方法,那么您的类设计得很糟糕” 如果类很复杂,则需要将其分离出来 所以,我需要你的帮助 问题班 因此,我有一个相对简单的类,它的长期运行工作是: 轮询数据源 对数据进行一些非常简单的映射 将数据发送到其他地方 另外: 它需要能够在出现某些错误时重试各种任务,从而具有相当的容错能力 测试问题 该类的要点是抽象出许多容错和线程。。。基本上是通过使用一个简单的计时器类和一些内部列表来跟踪错误等 由于计

关于测试复杂类和私有方法的主题,我已经读了很多书

普遍的共识似乎是:

  • “如果您需要测试私有方法,那么您的类设计得很糟糕”
  • 如果类很复杂,则需要将其分离出来
所以,我需要你的帮助

问题班 因此,我有一个相对简单的类,它的长期运行工作是:

  • 轮询数据源
  • 对数据进行一些非常简单的映射
  • 将数据发送到其他地方
另外:

  • 它需要能够在出现某些错误时重试各种任务,从而具有相当的容错能力
测试问题 该类的要点是抽象出许多容错和线程。。。基本上是通过使用一个简单的计时器类和一些内部列表来跟踪错误等

由于计时器的原因,某些方法会在不同的线程上异步调用。。。此外,一系列方法依赖于全局私有字段

我应该如何测试这个类。。。特别是因为这么多方法是私有的


干杯伙计们

你们可以试着用类似的东西。这将使您可以用可以控制的模拟计时器替换真实计时器。然后,您可以设置以定义的顺序触发方法调用的测试用例,还可以通过创建模拟数据源来设置错误条件


编辑:哇!没有看到C#标签。也许有一个C#等价于JMock。

我会提取代码,将数据轮询到一个可以模拟的单独类中,并提取出于相同原因发送数据的代码。您可能希望提取数据映射代码,这取决于它的琐碎程度

我肯定会在单元测试中使用模拟计时器,否则您的测试很难设置并且运行缓慢。您可以在构造函数中传入计时器,也可以公开可以设置的属性。我经常在构造函数中创建一个常规计时器,然后从单元测试中重写它

您还可以提取重试逻辑,以便可以将其与其他代码分开进行测试。将代码的委托传递给try和retry可能是将数据代码与重试逻辑分离的一种方法。您还可以使用
IEnumerable
yield
语句生成数据并将其提供给重试代码。本质上,我正在寻找方法使重试代码不会直接调用它应该反复尝试的目标代码。这使得测试和生成所有可能的错误变得更加容易,尽管您可以通过模拟目标代码获得一些相同的好处


如果您确实需要测试多线程场景,那么有一些工具可以在测试中协调线程。其中一个是我创建的一个名为的端口。

+1谢谢cameron,太棒了!我考虑过,但这是否意味着我应该在构造函数中作为依赖项传入计时器。当前是在内部实例化的。干杯,曼特里奇。最好不要仅仅为了适应您的测试制度而更改接口。我看到你将计时器间隔作为参数传递,所以也许你可以通过各种计时测试一系列错误条件(当然还有非错误条件)。是的。。。。这有点棘手,不是吗。。。我在想也许可以模仿ILogger,然后我可以检查各种日志消息何时被调用。。。?有点假,但…?没关系-嘲笑记录器没有什么错。然后,您可以检查它是否发出预期的日志消息。+1回答很好,谢谢。。。。我想将代码解耦,但它似乎过度依赖于全局变化的值。这肯定是个问题,但也是它使类如此易于使用的原因…?我不知道它是否适用于您的情况,@Andy,但使用IEnumerable和yield通常可以让您使用局部变量而不是成员变量跟踪状态。这可能会使代码更容易解耦,并且仍然保持简单易用。