Передача локальной переменной потока в тест JUnit

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

public class FooThread extends Thread {
    TestRunner runner;
    Foo foo;

    public void run() {
        initSomeThreadLocalStuff(); // inits foo and runner
        runner.runJUnitTests(); // JUnitCore.runTest(TestClass)
    }

    private void initSomeThreadLocalStuff() {
        foo = new Foo(this);
        // ...
    }
}

public class Foo() {
    public Foo(FooThread t) {
        // ...
    }    
}

Теперь я хочу запустить тесты JUnit с доступом (или ссылкой) к локальному объекту потока foo, Это возможно? Я пытался сделать это простым, но сложная вещь казалась непонятной (поэтому я добавил немного кода): объект Foo нуждается в текущем FooThread быть инициализированным.

2 ответа

Понятия не имею, зачем вам нужен ThreadLocal. если вам нужно запустить одни и те же тесты с разными параметрами, просто создайте список этих параметров и используйте параметризованные тесты (нативные или из множества библиотек, таких как zohhak или junit-dataprovider).

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

Похоже, что вам нужны параметризованные модульные тесты JUnit.

Изменить: Пример кода на основе примера, представленного в вики JUnit:

@RunWith(Parameterized.class)
public class Test {

    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {{ new ThreadLocalProvider() }});
    }

    @Parameter(value = 0) // first data value (0) is default
    public /* NOT private */ ThreadLocalProvider tloProvider;

    public ThreadLocal<Object> tlo;

    @Before
    public void setup() {
        // getNew() will be called in the same thread in which the unit test will run.
        tlo = tloProvider.getNew();
    }

    @Test
    public void test() {
        // Test using tlo.
    }
}

class ThreadLocalProvider {
    public ThreadLocal<Object> getNew() {
        // Instantiate a *new* ThreadLocal object and return it.
    }
}

Примечание. Если вы используете провайдера, вы можете запускать свои тесты без использования Parameterized Runner (просто получите новый объект от провайдера в @Before метод), но так как я мало знаю о вашем коде или требованиях, я оставлю этот выбор вам.

Кроме того, вам не нужно создавать свой собственный JUnit Runner. Вы можете использовать Runner предоставленный JUnit ( ссылка) вместе с @RunWith аннотаций.

Другие вопросы по тегам