Junit повторно инициализирует класс при каждом вызове метода тестирования?

Когда я запускаю приведенный ниже код, выполняются оба тестовых примера:

import static junit.framework.Assert.assertEquals;

import org.junit.Test;

public class MyTest{
    private int count;

    @Before
    public void before(){
        count=1;
    }

    @Test
    public void test1(){
        count++;
        assertEquals(2, count); 
    }

    @Test
    public void test2(){
        count++;
        assertEquals(2, count); 
    }
}

ОЖИДАЕМОЕ ПОВЕДЕНИЕ

  • test1 - успех
  • test2 - fail (как ожидается, число будет 3)

АКТУАЛЬНОЕ ПОВЕДЕНИЕ

  • test1 - успех
  • test2 - успех

Почему junit reinitializing class/variable с каждым вызовом метода. Это ошибка в junit или предоставляется намеренно.

Ответ 1

Новый экземпляр MyTest для каждого метода тестирования

Для каждого тестового метода будет создан новый экземпляр MyTest, это поведение Junit.

Итак, в вашем случае для обоих методов переменная count будет иметь значение 1, и поэтому значение count++ будет 2 для обоих методов тестирования, и, следовательно, тестовые примеры пройдут.

public class MyTest{
   public MyTest(){
      // called n times
      System.out.println("Constructor called for MyTest");
   }

   @Before //called n times
   public void setUp(){
      System.out.println("Before called for MyTest");
   }

   //n test methods
}

Если вы выполните код выше с помощью двух методов тестирования:

Выход будет:

Constructor called for MyTest
Before called for MyTest
//test execution
Constructor called for MyTest
Before called for MyTest

Ответ 2

Это из-за изоляции теста.

Никакой тест не должен зависеть от другого.

Ответ 3

Посмотрите документацию org.junit.runner.Runner:

Стандартная реализация runner гарантирует, что экземпляры класс тестового случая будет создан непосредственно перед запуском тест, и что бегун не будет ссылаться на тестовый пример экземпляров, что делает их доступными для сбора мусора.

Единичные тесты должны быть независимыми, иначе он станет незаменимым. Обратите внимание, что порядок выполняемых методов не гарантируется (если вы не используете аннотацию @FixMethodOrder).

Ответ 4

Не инициализируйте состояние тестового класса в конструкторе, если он не является неизменным.

JUnit не создает экземпляр вашего тестового класса для каждого @Test. На самом деле он запускает только методы, отмеченные @Before перед каждым, и будет запускать методы @BeforeClass один раз перед всеми тестами в классе.

Однако вам не гарантировано, что тестовый бегун фактически будет использовать только один экземпляр вашего тестового класса для запуска тестов. Вы можете использовать многие из них - подумайте о параллельном запуске тестов, даже на разных компьютерах.

Несмотря на то, что для этого вообще есть настройки JUnit runner, гораздо лучше просто следовать дизайну JUnit и инициализировать тестовое состояние только методом @Before.

Ответ 5

Если вы хотите использовать переменную-член класса тестирования для всех тестов, без повторной инициализации до нуля, сделайте ее статической.