Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.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
Java 什么';测试类静态初始值设定项的最佳方法是什么?_Java_Junit_Static Initializer - Fatal编程技术网

Java 什么';测试类静态初始值设定项的最佳方法是什么?

Java 什么';测试类静态初始值设定项的最佳方法是什么?,java,junit,static-initializer,Java,Junit,Static Initializer,我有一个类,它有相当复杂的静态初始化。我从一个目录中读取文件,然后解析这些json文件,映射到对象,并填写一个列表。您可以想象,可能会出现一些异常,我需要介绍并测试这些代码分支。问题是这个静态初始化只运行一次/Testcase文件。 我跨越的解决方案: 每个行为的新测试用例文件 卸载静态类 新JVM 我对这些选项不感兴趣,难道没有更好的方法吗?如果您无法避免静态初始值设定项,请将其提取到方法体。然后是测试方法。静态初始值设定项看起来像是static{myMethod();},几乎不能被破坏。

我有一个类,它有相当复杂的静态初始化。我从一个目录中读取文件,然后解析这些json文件,映射到对象,并填写一个列表。您可以想象,可能会出现一些异常,我需要介绍并测试这些代码分支。问题是这个静态初始化只运行一次/Testcase文件。 我跨越的解决方案:

  • 每个行为的新测试用例文件
  • 卸载静态类
  • 新JVM

我对这些选项不感兴趣,难道没有更好的方法吗?

如果您无法避免静态初始值设定项,请将其提取到方法体。然后是测试方法。静态初始值设定项看起来像是
static{myMethod();}
,几乎不能被破坏。

单元测试中的一个重要因素是对代码进行结构化,使其适合测试

不幸的是,正如您所发现的,执行复杂IO操作的静态初始化过多的代码不是一个容易测试的结构

除了静态初始化之外,听起来您的代码违反了in,就像一个类从外部源加载自己一样,可能还有其他用途

因此,您需要进行一些重构,例如,如果您的代码看起来像这样(为了清晰起见,JSON解析替换为CSV解析):

如果看不到您的代码或不知道文件格式,很难对其进行扩展,但希望您能了解要点

最后,静态初始化将是:

public MyClass
{
  private static List<MyObject> myObjects = new ArrayList<>();

  static
  {
    loadMyObjects(new FileReader("myfile.csv"));
  }

  /* package */ static void loadMyObjects(Reader reader)
  {
    try
    {
      try (MyObjectReader reader = new new MyObjectReader(reader))
      {
        MyObject myObject;

        while ((myObject = reader.read()) != null) 
        {
          myObjects.add(myObject);
        }
      }
    }
    catch (IOException e)
    {
      ...
    }
  }
}    
公共MyClass
{
私有静态列表myObjects=newarraylist();
静止的
{
loadMyObject(新文件阅读器(“myfile.csv”);
}
/*包*/静态无效加载对象(读卡器)
{
尝试
{
try(MyObjectReader=新建MyObjectReader(reader))
{
肌体肌体;
while((myObject=reader.read())!=null)
{
myObjects.add(myObject);
}
}
}
捕获(IOE异常)
{
...
}
}
}    

在这里测试快乐之路可能是值得的,但就我个人而言,
loadMyObjects
方法现在非常简单,我可能不会费心了。

可能是Wow的复制品,感谢您提供了全面详细的答案。对于IO繁重的任务,单独的reader类是一个好主意。Nick Holt给出了更详细的答案,但基本思想是一样的。谢谢:)
public class MyObjectReader implements Closeable
{
  private BufferredReader reader;

  public MyObjectReader(Reader reader)
  {
    this.reader = new BufferredReader(reader);
  }

  public MyObject read() throws IOException
  {
    String line = reader.readLine();

    if (line != null)
    {
      String[] tokens = line.split(",");

      if (tokens.length < 3)
      {
        throw new IOException("Invalid line encountered: " + line);
      }

      return new MyObject(tokens[0], tokens[1], tokens[2]);
    }
    else
    {
      return null;
    }
  }

  public void close() throws IOException
  {
    this.reader.close();
  }
}
public MyObjectReaderTest
{
  @Test
  public void testRead() throws IOException
  {
    String input = "value1.1,value1.2,value1.3\n" +
      "value2.1,value2.2,value2.3\n" +
      "value3.1,value3.2,value3.3";

    try (MyObjectReader reader = new MyObjectReader(new StringReader(input)))
    {
      assertEquals(new MyObject("value1.1", "value1.2", "value1.3"), reader.read());
      assertEquals(new MyObject("value2.1", "value2.2", "value2.3"), reader.read());
      assertEquals(new MyObject("value3.1", "value3.2", "value3.3"), reader.read());
      assertNull(reader.read());
    }
  }

  @Test(expected=IOException.class)
  public void testReadWithInvalidLine() throws IOException
  {
    String input = "value1.1,value1.2";

    try (MyObjectReader reader = new MyObjectReader(new StringReader(input)))
    {
      reader.read();
    }
  }
}
public MyClass
{
  private static List<MyObject> myObjects = new ArrayList<>();

  static
  {
    loadMyObjects(new FileReader("myfile.csv"));
  }

  /* package */ static void loadMyObjects(Reader reader)
  {
    try
    {
      try (MyObjectReader reader = new new MyObjectReader(reader))
      {
        MyObject myObject;

        while ((myObject = reader.read()) != null) 
        {
          myObjects.add(myObject);
        }
      }
    }
    catch (IOException e)
    {
      ...
    }
  }
}