我上课了
我在该类的构造函数中初始化一个变量
我调用一个包含while
循环的方法,并每次递增变量。
我编写了一个测试来检查方法被调用后的变量值(并通过while循环一次)。
public class ThreadGenerator implements Runnable {
private int requests;
private int limit;
public ThreadGenerator() {
requests = 0;
}
public void setRequestLimit(int anyLimit) {
this.limit = anyLimit;
}
public void generateThread() {
new Thread(this).start();
}
public void run() {
while(requests < limit) {
try {
// do some stuff
requests++;
// close some stuff
} catch (IOException e) {
e.printStackTrace();
}
}
}
public int getRequests() {
return requests; // calling this method from my tests always returns 0
}
在我的测试中,当我创建此类的新实例时,然后在该类上调用此方法,它正确运行并正确递增请求计数器。我已经尝试了几个打印语句来确保这一点。但是,如果我在测试中的getRequests
对象上调用ThreadGenerator
,它将返回0,即初始化的数量。
我的测试代码:
ThreadGenerator threadGenerator = new ThreadGenerator();
threadGenerator.setRequestLimit(1);
threadGenerator.generateThread();
assertEquals(threadGenerator.getRequests(), 1);
如何修改我在构造函数中初始化的变量并在我的测试套件中获取对它的访问权?
答案 0 :(得分:5)
请记住,仅仅因为您要求Java使用Runnable创建新线程,并不意味着将立即调用run()
方法。可能是assertEquals
在run
第一次发生之前发生的情况。
您可能希望返回线程并在生成的线程上的测试中调用join
,这将确保线程运行直到它死亡,可能是短暂的超时。
/* in the system under test */
@VisibleForTesting Thread generateAndReturnThread() {
Thread thread = new Thread(this);
thread.start();
return thread;
}
public void generateThread() {
generateAndReturnThread();
}
/* in the test */
@Test public void yourTest() {
ThreadGenerator threadGenerator = new ThreadGenerator();
threadGenerator.setRequestLimit(1);
// wait up to a second for thread to complete
threadGenerator.generateThreadAndReturn().join(1000);
assertEquals(threadGenerator.getRequests(), 1);
}
附注:如果多个线程可能修改requests
,请考虑AtomicInteger
您的请求类。这将有助于防止两个不同的线程同时修改requests
并相互覆盖。
答案 1 :(得分:1)
除了上述答案之外,考虑将变量声明为volatile,以便在另一个线程增加变量后实际获取最新值。