-1

我一直在尝试让 Junit 测试等待异步任务完成但被卡住了。假设我们有这样的课程

class MyViewModel{

 public void doSomething(){

    new Task(){

      void inBackground(){
         model.getData(); //Executes for 4000 ms max

      void onMainThread(){
         displayData();
      } 


    } 

 }

  void displayData(){

  } 
}

这是我的测试方法

@UiThreadTest
@Test
public void someTest() throws Exception{
   MyViewModel myViewModel = Mockito.spy(new MyViewModel());
   myViewModel.doSomething();
   Thread.sleep(5000);
   verify(myViewModel).displayData();          
} 

我面临的问题是该verify语句之前displayData在内部类中被调用MyViewModel并且测试用例失败。我该如何解决这个问题?也欢迎任何其他测试相同功能的方式。

4

2 回答 2

0

我通过使用处理程序解决了这个问题。

在测试类的 setUp 方法中,我创建了一个处理程序。

@UiThreadTest
@Before
public void setUp() throws Exception {
    handler = new Handler();
}

请注意,我使用 @UiThreadTest 注释将处理程序与 UiThread 相关联。

在测试方法中,我使用处理程序在 ui 线程上运行 viewmodel 代码,并在不同线程上运行验证方法。请注意,我在这里删除了 @UiThreadTest 注释。

@Test
public void testThatInspectionsAreFetchedWhenVesselIdIsSet() throws Exception{
    MyViewModel myViewModel = Mockito.spy(new MyViewModel());
    handler.post(() -> myViewModel.doSomething());
    Thread.sleep(5000);
    verify(myViewModel).displayData(); 
  } 

现在测试方法完美运行!

于 2018-05-04T06:25:27.700 回答
0

我更喜欢使用CountDownLatch

final CountDownLatch signal = new CountDownLatch(1);


   public void someTest() throws Exception{
     MyViewModel myViewModel = Mockito.spy(new MyViewModel());
     myViewModel.doSomething();
     // It will wait either 5 secs or your countDown signal from 
     //postexecute from task
     signal.await(5, TimeUnit.SECONDS);
     verify(myViewModel).displayData();          
    }

您还应该signal.countDown()从执行后调用。如果您不想等待 5 秒并且您只想确保验证仅在您完成后台进程后运行而不是在signal.await()

于 2018-05-03T12:27:13.843 回答