如何编写创建新线程的单元测试



我有以下测试方法:

public class classToTest{
    @Autowired
    private Alternator alternator;
     public void methodToTest(){
         Thread t = new Thread(new Runnable() {
             public void run() {
                 while(true) {
                     if(alternator.get()) {
                         System.out.print("Hello");
                         alternator.set(false);
                     }
                 }
             }
          };
          t.start()
    }
}

我需要检查被调用的方法

alternator.set(false);

我该怎么做?

您可以传入一个"Executor"实例而不是直接启动线程吗?

例如。。。

public class ClassToTest{
    @Autowired
    private Alternator alternator;
    @Autowired @Qualifier("myExecutor")
    private java.util.concurrent.Executor executor;
    public void methodToTest() {
        Runnable runnable = new Runnable() {
           public void run() {
               while(true) {
                 if(alternator.get()) {
                     System.out.print("Hello");
                     alternator.set(false);
                 }
             }
        };
        executor.execute(runnable);
    }
}

现在你可以更容易地测试。。。

public class ClassToTestTest {
    ...
    @Before
    public void setup() {
        alternator = mock(Alternator.class);
        executor = mock(Executor.class);
        obj = new ClassToTest();
        ReflectionTestUtils.setField(obj, "alternator", alternator);
        ReflectionTestUtils.setField(obj, "executor", executor);
    }
    @Test
    public void shouldStartRunnable() {
        obj.methodToTest();
        ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
        verify(executor).execute(runnableCaptor.capture());
        Runnable runnable = runnableCaptor.getValue();
        // Now test your actual "runnable"...
        when(alternator.get()).thenReturn(true);
        runnable.run();
        verify(alternator).set(false);
    }
}

(我还没有尝试编译这个,所以如果有任何错误,我深表歉意!!)

尽管非常推荐Bret传递执行器的帖子,但您可以使用timeout()模拟验证设置来测试异步条件。

verify(alternator, timeout(500)).set(false);

请注意,这必然会增加测试的片状性(即代码通过时测试失败的可能性)。有了合理的超时值,这种不稳定应该可以忽略不计,但如果你将其作为核心测试基础设施的一部分,你可能会考虑重构,以允许在测试中同步执行。

最新更新