我正在尝试为Threads编写测试用例,这是由其他人编写的。
我没有改变现有代码的自由。我在这个论坛中经历了各种各样的线程,但似乎没有什么工作适合这种情况。请建议。
我的代码如下:
Class X implements Runnable{
Y y;
public X(){}
public X(Y y){
this.y = y;
}
public void run(){
Y.staticVoidMethod(A a, B b, boolean c);
}
}
然后在下面的另一个班class Main
写下:
class Main{
public static void main1(){
Y y=new Y();
new Thread(new X(y)).start();
}
}
我的测试课如下:
class Test {
Thread thread;
X x;
Y y = spy(new Y());
@BeforeMethod(alwaysRun = true)
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
PowerMockito.mockStatic(Y.class);
x= spy(new X(y));
thread = spy(new Thread(x));
whenNew(X.class).withAnyArguments().thenReturn(x);
whenNew(Thread.class).withArguments(x).thenReturn(thread); // I have also tried ......withArguments(X.class).thenReturn(thread)
}
@Test
public void test1(){
Main.main1();
//none of the below is working
verify(thread).start();
verify(x).run();
assertTrue(thread.isAlive());
}
}
答案 0 :(得分:2)
正如评论者所说,不要测试Thread.start()
- 它有效。
您可以使用X.run()
测试您的课程:
原则上:
@Test
public void runs() {
Y y = ...; // could be a mock
X x = new X(y);
x.run();
assertThat( ... probably something about y ...);
}
您真正的问题是您正在调用静态方法。静态方法往往难以测试,这只是他们经常做出糟糕设计选择的一个原因。
请注意,在您提供的代码中,您传递了Y
的实例,但之后您就不会使用它。静态调用Y.staticVoidMethod()
与您传入的Y
,y
实例无关。
答案 1 :(得分:1)
其他答案/评论是正确的。但这里有一个重要的方面:为了测试给定的代码,你需要进行这样的测试。
换句话说:有两个要测试的东西。您首先创建一个类XTest
,其中包含X
内所有有意义的测试。
(可能需要您使用PowerMock(ito)来测试静态方法调用)。
然后,您可以编写一个MainTest
类,以确保Main.main()
执行预期的操作。那将是:创建一个X的实例,并将其传递给一个新的线程。是的,测试会一路上隐式测试Thread.start()。此外,您还需要PowerMock(ito)进行new X()
调用。
要理解的重要事项是:您不需要验证Thread.start()是否有效;但是你的测试用例可能必须知道调用Thread.start();确保它能够发挥作用。
但是:很有可能,你在浪费你的时间。您应该测试的传入代码似乎质量很差。从那里:测试代码有什么意义......当你不允许更改生产代码时?如果您的测试发现错误会发生什么?把这个bug留在代码中?!
所以真正的答案更像是:对付给你这个任务并澄清要求的人。因为当前的要求不会使感觉。也许让他们看this - 所以他们将来会学习如何编写可测试的代码。你是关于战斗糟糕设计的症状。而最常见的答案是修复糟糕的设计;而不是解决由该设计引起的问题!
单独认为X有一个Y成员字段y ...然后在Y上进行静态调用真的很奇怪......