Java 将线程局部变量传递给JUnit测试

Java 将线程局部变量传递给JUnit测试,java,junit,thread-local,parameterized-unit-test,Java,Junit,Thread Local,Parameterized Unit Test,我有一个线程,它初始化一个线程本地类变量,并从运行单元测试开始: public class FooThread extends Thread { TestRunner runner; Foo foo; public void run() { initSomeThreadLocalStuff(); // inits foo and runner runner.runJUnitTests(); // JUnitCore.runTest(Tes

我有一个线程,它初始化一个线程本地类变量,并从运行单元测试开始:

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) {
        // ...
    }    
}
现在,我想通过对线程本地对象
foo
的访问(或引用)来运行JUnit测试。这可能吗?我试图保持简单,但复杂的事情似乎并不清楚(因此我添加了一些代码):Foo对象需要初始化当前的
FooThread

看起来JUnit就是您要找的

编辑:基于JUnit wiki上提供的示例的示例代码:

@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.
    }
}
@RunWith(参数化的.class)
公开课考试{
@参数
公共静态收集数据(){
返回Arrays.asList(新对象[][{{new ThreadLocalProvider()}});
}
@参数(值=0)//默认为第一个数据值(0)
public/*非private*/ThreadLocalProvider tloProvider;
公共和本地tlo;
@以前
公共作废设置(){
//getNew()将在运行单元测试的同一线程中调用。
tlo=tloProvider.getNew();
}
@试验
公开无效测试(){
//使用tlo进行测试。
}
}
类ThreadLocalProvider{
公共线程本地getNew(){
//实例化一个*新*线程本地对象并返回它。
}
}
注意:如果您使用提供程序,您也可以在不使用参数化运行程序的情况下运行测试(只需在
@Before
方法中从提供程序获取一个新对象),但由于我对您的代码或需求知之甚少,我将把这个选择留给您


此外,您不需要实例化自己的JUnit Runner。您可以使用JUnit()提供的
Runner
以及
@RunWith
注释。

不知道为什么需要threadLocal。如果您需要使用不同的参数运行相同的测试,那么只需创建这些参数的列表并使用参数化测试(junit的本机或许多库,如zohhak或JUnitDataProvider)


如果出于任何原因需要访问测试中的本地线程,那么还需要在测试中向其插入数据,因为在运行测试之前,您不知道将使用哪个线程来运行测试。但似乎您仍然可以编写一个测试来检查您的代码是否正确使用threadLocal,然后参数化测试来检查您的代码是否正确处理从threadLocal获取的值

我插入了一些重要的代码部分,这些部分一开始可能不清楚,我认为您的解决方案无法解决我的问题。tlo需要对当前MyThread的引用进行初始化。您可以随意实例化
tlo
(甚至在测试类或
data()
方法之外)。由
data()返回的
集合
方法也可以由另一个类/实例生成。它需要在测试运行时在同一个线程中实例化。我不熟悉Java的ThreadLocal,但MyThread在您的答案中的位置是什么?您不能在没有MyThread或没有MyThread的情况下创建ThreadLocal对象。请阅读:。每个Java代码都将在某个线程中运行-ThreadLocal变量将绑定到实例化它的线程(因此而得名).ThreadLocals不需要显式包装在
线程
可运行
对象中。每个
@Test
方法之前都会运行
@Before
方法,因此在
@Before
中创建的任何ThreadLocal变量都将在单元测试的线程中创建。请阅读JUnit的
@Before
注释我也是。