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

3

我有以下测试方法:

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);

我该如何做?


alternator 是什么?在被测试的代码中它是如何创建的? - user1907906
1
我们需要知道“交流发电机(alternator)”,因为您可能需要模拟它来测试。因此,“服务(service)”这个词有点太笼统了。 - markspace
我已经更新了主题。这样足够了吗? - gstackoverflow
你已经标记了你的问题为 mockito。你尝试过模拟 alternator 吗? - user1907906
并发问题:我不确定该方法是否在验证之前被调用。 - gstackoverflow
显示剩余2条评论
2个回答

0

你可以传入一个“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);
    }
}

(我还没有尝试编译这个,如果有任何错误,请谅解!)


0

尽管建议使用Bret的文章来传递执行者,但您可以使用timeout()模拟验证设置来测试异步条件。

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接