Как я могу узнать, выполняется ли код внутри теста JUnit или нет? - PullRequest
51 голосов
/ 26 февраля 2010

В моем коде мне нужно делать определенные исправления только тогда, когда он запускается внутри теста JUnit. Как я могу узнать, выполняется ли код внутри теста JUnit или нет? Есть ли что-то вроде JUnit.isRunning () == true?

Ответы [ 11 ]

46 голосов
/ 04 октября 2012

Это может быть хорошей идеей, если вы хотите программно решить, какой «профиль» запустить. Подумайте о Spring Profiles для конфигурации. Внутри интеграционных тестов вы можете протестировать другую базу данных.

Вот это проверенный код, который работает

public static boolean isJUnitTest() {
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    List<StackTraceElement> list = Arrays.asList(stackTrace);
    for (StackTraceElement element : list) {
        if (element.getClassName().startsWith("org.junit.")) {
            return true;
        }           
    }
    return false;
}
23 голосов
/ 26 февраля 2010

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

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

16 голосов
/ 24 апреля 2014

Многие люди в этой теме говорят, что плохая идея, чтобы код работал немного по-другому, пока работает под JUnit. Я в целом согласен, но я думаю, что есть некоторые исключения.

Например, я сейчас пишу тесты INTEGRATION (в отличие от Unit) для приложения, которое подключается к БД.

Эти приемочные испытания часто требуют полной повторной инициализации БД с конкретными данными испытаний.

Очевидно, я не хочу, чтобы это КОГДА-ЛИБО было сделано на реальной производственной базе данных, потому что это могло бы полностью стереть ценные производственные данные.

Самый простой способ гарантировать, что этого никогда не произойдет, состоит в том, чтобы лишить код возможности подключаться к производственной БД, когда он работает под JUnit. Это, в свою очередь, может быть сделано, если, например, Factory, которая генерирует соединение, может сказать, что работает под JUnit, и в этом случае вернет нулевое соединение, если только база данных, к которой мы пытаемся подключиться, не имеет известного имени. быть тестовой базой данных (например, «testdatabase»).

10 голосов
/ 14 августа 2012

Я могу найти оправдание этому, когда вы хотите предоставить код в производственном классе, чтобы помочь тестированию.Это будет похоже на Java assert, который применяется только при установленном флаге отладки.

Примерно так:

Object debugState() {
    // This is only meant to be called when testing
    if (!JUnit.isRunning()) {
        throw new IllegalStateException("Not in a test!");
    }
    // Now compute possibly costly debug information
    // not to be used in production
    Object state = ...
}
4 голосов
/ 27 августа 2015

Как насчет проверки того, находится ли баночка джунита в пути к классам?

4 голосов
/ 26 февраля 2010

Если вы делаете что-то по-другому, потому что вы проводите юнит-тест, вы побеждаете цель юнит-теста. Предполагается, что модульный тест будет работать точно так же, как и в производственном режиме (за исключением настройки и разборки любых необходимых данных, необходимых вам ... но это входит в сам тест JUnit, а не в ваш код).

Однако, если у вас действительно есть на то веские причины, я бы посмотрел на стек и посмотрел, есть ли там JUnit.

2 голосов
/ 23 апреля 2015

При использовании Spring можно определить бин, который содержит это значение.

В контексте приложения:

@Bean
public boolean isRunningTests() {
    return false;
}

В контексте тестового приложения:

@Bean
public boolean isRunningTests() {
    return true;
}

Вставить значение в компонент Spring:

@Resource
private boolean isRunningTests;

private void someMethod() {
    if (isRunningTests()) {
        ....
0 голосов
/ 12 июня 2019

Это сработало для меня:

private Boolean isRunningTest = null;

private boolean isRunningTest() {
    if (isRunningTest == null) {
        isRunningTest = true;
        try {
            Class.forName("org.junit.Test");
        } catch (ClassNotFoundException e) {
            isRunningTest = false;
        }
    }
    return isRunningTest;
}

Может использоваться в тестах Maven, а также в Eclipse IDE, если в качестве зависимости с областью действия "test" включена junit, например:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
</dependency>
0 голосов
/ 22 сентября 2017

Самое короткое (с наименьшим кодом) решение состоит в том, чтобы иметь глобальный флаг, который устанавливается, когда тесты не запущены.Затем вы можете установить его один раз в main() (или аналогичной точке входа), вместо того, чтобы устанавливать его повторно в методах настройки всех тестовых классов.Это будет работать до тех пор, пока нет другого способа ввода кода (без альтернативы main).

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

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

0 голосов
/ 13 июля 2017

Чтобы отличить тест от теста, вы всегда можете определить специальное свойство или значение в application-test.properties.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...