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
注释我也是。