Пропустить @Before для теста || Есть ли способ выполнить методы @Before в TestRule?

Высокий уровень, у меня есть тестовый класс JUnit, который довольно прост. У меня есть несколько @Tests и один @Before, который выполняет некоторые настройки. Для одного тестового случая настройка меняется (я не хочу, чтобы она запускалась).

Из некоторых поисков я нашел /questions/28694659/isklyuchit-otdelnyij-test-iz-metoda-do-v-junit/28694684#28694684. Это предполагает создание @Rule, который проверяет конкретную аннотацию и выполняет оператор @Before.

Моя путаница заключается в том, как выполнить метод @Before в правиле. Есть способ сделать это? Или мне нужно передать сам тестовый класс и выполнить метод @before (setup() в приведенном ниже примере)?

public class NoBeforeRule implements TestRule {

    @Override
    public Statement apply(final Statement base, final Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                if (description.getAnnotation(NoBefore.class) == null) {
                    // Is there something like `base.executeAllTheBefores()' 
                }

                base.evaluate();
            }
        };
    }
}

Соответствующий код теста:

@Rule public NoBeforeRule mNoBeforeRule = new NoBeforeRule(this);

@Before
@Override
public void setup() {
}

@Test
public void testNeedSetup() {
    // this should run setup()
}

@NoBefore
@Test
public void testNoSetup() {
    // this should NOT run setup()
}

3 ответа

Почему бы вам просто не разделить тесты на 2 отдельных класса тестов? Те, кому нужна настройка, входят в один класс, а те, которые не входят в другой.

Не существует правила (или даже руководства), согласно которому все тесты для класса должны входить в один тестовый класс, и на самом деле это то, что я делаю очень часто.

Тот факт, что у вас есть один или несколько тестов, которые не нуждаются в общей настройке, вероятно, свидетельствует о том, что сами тесты не являются связными и тестируют другой вариант тестируемого класса. Например, у меня может быть куча методов, которые специально настраивают фиктивные настройки для положительных тестов, но затем другие тесты, которые нуждаются в другой конфигурации для сценариев сбоев. Я перенесу эти тесты в 2 класса - специально для положительных и неудачных сценариев.

Игра с Правилами и тому подобное, чтобы явно избежать запуска стандарта @Before метод только усложнит ситуацию и заставит вашего будущего или коллег почесать голову, почему метод установки не запускается

Может поиграться с правилом TestName

@Rule public TestName name = new TestName();

@Before 
public void setup() {
     if(listOfTestNeedSetup.contains(name.getMethodName()) {
        // need setup
     }
}
  • вызовите setup() в пользовательской реализации правила.

  • удалите аннотацию @Before в setup(), так как включение @Rule приведет к тому, что пользовательское правило будет запускаться каждый раз.

            public class MyTest {
    
       class NoBeforeRule implements TestRule {
          @Override
          public Statement apply(final Statement base, final Description description) {
              return new Statement() {
                  @Override
                  public void evaluate() throws Throwable {
                      if (description.getAnnotation(NoBefore.class) == null) {
                          setup(); 
                      }
    
                      base.evaluate();
                  }
              };
          }
       }
    
       @Rule 
       public NoBeforeRule mNoBeforeRule = new NoBeforeRule();
    
    
       public void setup() {}
    
       @Test
       public void testNeedSetup() {
          // this should run setup()
       }
    
       @NoBefore
       @Test
       public void testNoSetup() {
          // this should NOT run setup()
       }
    }
    
Другие вопросы по тегам