新线程的单元测试(...)。start()

时间:2017-06-19 10:18:09

标签: java multithreading unit-testing

我正在尝试为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());
      } 
}

2 个答案:

答案 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()与您传入的Yy实例无关。

Mocking static methods with Mockito可能会有所帮助。

答案 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上进行静态调用真的很奇怪......