如何使类更具可测试性

本文关键字:可测试性 何使类 | 更新日期: 2023-09-27 18:08:18

我有这个:

 class FooGenerator:IFooGenerator {
      private object _generated;
      public void Generate() {
         // Generating
         GenerateSmallPart();
         GenerateOtherSmallPart();
         GenerateTinyPart();
         // A lot similar
      }
      private void GenerateSmallPart() {
         //add small part to _generated
      }
      private void GenerateOtherSmallPart() {
         //add small part to _generated
      }
      private void GenerateTinyPart() {
         //add small part to _generated
      }
   }
   internal interface IFooGenerator {
      void Generate();
   }

在我的应用程序中,我只使用IFooGenerator通过IoC,但我想测试所有这些子方法。

正如我在这里发现的,一种选择是提取具有所有子方法的类。但我为什么要这么做。仅在FooGenerator中使用

你有什么建议我怎样才能使我的类更可测试吗?

如何使类更具可测试性

我将与你分享我通常是如何处理这种情况的。如果我发现由于某种原因(比如很难存根输入参数来测试所有代码流),我想测试一些私有方法——这通常意味着我的类的复杂性很高,我需要重构我的代码。在你的情况下(我不知道你的方法在做什么),你可以使用这样的东西:

interface IPartGenerator
{
   void GeneratePart();
}
class SmallPartGenerator : IPartGenerator
{
   void GeneratePart();
}
class OtherSmallPartGenerator : IPartGenerator
{
   void GeneratePart();
}
class TinyPartGenerator : IPartGenerator
{
   void GeneratePart();
}
class FooGenerator:IFooGenerator 
{
   private IPartGenerator[] partGenerators = new IPartGenerator[] 
                        {
                           new SmallPartGenerator(), 
                           new OtherSmallPartGenerator(), 
                           new TinyPartGenerator ()
                        }
   public void Generate()
   {
        foreach (var partGenerator in partGenerators)
        {
              partGenerator.GeneratePart();
        }
   }
}

现在您可以分别测试每个部件生成器。

谁是客户?

许多人(Roy Osherove, Michael Feathers)认为测试客户端与接口或服务客户端一样有效。

考虑到这一点,我认为稍微违反封装原则是可以的,通过将一些私有方法设置为公共来打开可测试的接缝。

你的类不是做一件事,而是做几件事——每件事都封装在一个私有方法中。这违反了单一责任原则(SRP)。根据SRP,一个类应该只做一件事。

Neil Thompson建议你应该把私有方法变成公共方法。这至少使它们可以被单元测试访问,但是它们仍然是违反SRP的。如果你的班级有很多不同的东西,入会通常是复杂的;您必须在满足所有方法需求的状态下创建类,尽管您只想测试一个小角落。这对可测试性没有任何好处。

在此之后,outcoldman的答案是一个更健全的设计。他的代码没有违反SRP