Java IntelliJ逐个运行测试

Java IntelliJ逐个运行测试,java,intellij-idea,junit,Java,Intellij Idea,Junit,简而言之,我刚刚写了一个单身学生的课程。与all singleton一样,我的singleton由一个私有构造函数和一个包含预定义数量的类对象的静态字段组成 情况是-必须使用JSON文件初始化singleton类,预期的行为是当给定列表中没有文件时引发异常 问题在于,显然IntelliJ(或者可能只是JUnit)正在加载所有测试类,然后在一个程序中以随机顺序逐个执行它们。这意味着,当测试错误初始化的类到达时,单例已经初始化。这意味着每次我一次运行所有测试时,都会有一个测试未通过,当我手动逐个运行

简而言之,我刚刚写了一个单身学生的课程。与all singleton一样,我的singleton由一个私有构造函数和一个包含预定义数量的类对象的静态字段组成

情况是-必须使用JSON文件初始化singleton类,预期的行为是当给定列表中没有文件时引发异常

问题在于,显然IntelliJ(或者可能只是JUnit)正在加载所有测试类,然后在一个程序中以随机顺序逐个执行它们。这意味着,当测试错误初始化的类到达时,单例已经初始化。这意味着每次我一次运行所有测试时,都会有一个测试未通过,当我手动逐个运行测试时,会导致所有测试通过

有没有办法强制IntelliJ分别运行所有测试类

编辑

我不知道这会改变什么,但让我们假设它会。下面是一个具有完全相同行为的示例代码。这是一个IDE问题,而不是java特有的问题

public class Singleton {
    private static Singleton singleton = new Singleton();

    public static Singleton getInstance() {
        return singleton;
    }

    private Singleton() {
        if (!new File("maybeIExist.txt").exists())
            throw new ExceptionInInitializerError();
    }

    public void doStuff() {
        System.out.println("stuff");
    }
}
当然还有测试:

public class SingletonTestOne {
    @Test(expected = ExceptionInInitializerError.class)
    public void test() throws Exception {
        Singleton.getInstance();
    }
}
第二个:

public class SingletonTestTwo {
    @Before
    public void before() throws Exception {
        //code creating file
    }
    @Test
    public void test() throws Exception {
        Singleton.getInstance();
        doStuff();
    }
    @After
    public void after() throws Exception {
        //code deleting file
    }
}

这不是IntelliJ问题,运行
mvn测试时也会遇到同样的问题。您可以通过以下更改运行测试:

首先更改
Singleton
类,以便在
getInstance()
调用中创建
Singleton
字段,请注意,此方法现在需要
同步。您需要此选项才能重置字段

public final class Singleton {
  private static Singleton singleton = null;

  public static synchronized Singleton getInstance() {
    if (singleton == null) {
        singleton = new Singleton();
    }
    return singleton;
  }

  private Singleton() {
    if (!new File("maybeIExist.txt").exists()) {
        throw new ExceptionInInitializerError();
    }
  }

  public void doStuff() {
    System.out.println("stuff");
  }
}
接下来,在您的测试类中,您可以使用反射将
@Before
方法中的
singleton
字段重置为
null

import org.junit.Before;
import org.junit.Test;

import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static org.junit.Assert.fail;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsNull.notNullValue;

public class SingletonTest {

  @Before
  public void resetSingleton() throws NoSuchFieldException, IllegalAccessException {
    Field instance = Singleton.class.getDeclaredField("singleton");
    instance.setAccessible(true);
    instance.set(null, null);
  }

  @Test
  public void singletonCanFindFile() throws Exception {
    final Path path = Paths.get("maybeIExist.txt");

    Files.createFile(path);
    final Singleton instance = Singleton.getInstance();
    assertThat(instance, notNullValue());
    Files.deleteIfExists(path);
  }

  @Test(expected = ExceptionInInitializerError.class)
  public void singletonCannotFindFile() throws Exception {
      final Singleton instance = Singleton.getInstance();
      fail("no exception thrown!");
  }
}

粘贴singleton类的代码。我添加了它。我不知道代码是如何给问题添加任何内容的,但现在你知道了。你应该试试@ahrytsiuk。我将方法分组在不同的类中,因为它们检查不同的行为。除了上课,还有类似的事情吗?我需要在另一个测试用例中使用singleton,在它进入错误的初始化测试之前,它在那里被初始化。理论上,单元测试应该是独立的,这也许就是为什么。这里有一个讨论执行顺序的例子,但我认为它不会有用。在这种情况下,也许测试你的单身快乐/悲伤的具体道路可能是一条可行之路