使用Mockito时Java Futures返回null

时间:2018-08-06 21:27:21

标签: java junit mocking mockito powermockito

class Student{
int age;
String name;
}

class Demo{

public void getStudentList() {
Future<List<Student>> future = client.getAsyncData();
List<Student> response = futures.get(100l, TimeUnit
           .MILLISECONDS);
 }
}


class StudentTest{

  @Test
  public testData(){
  List<Student> students = new ArrayList();
  Client client = ClientFactory.getInstance();
  Future<List<Student>> mockFuture = mock(Future.class);
  when(client.getAsyncData()).thenReturn(mockFuture);
  when(mockFuture.get(10l,TimeUnit.MILLISECONDS)).thenReturn(students);

  Demo demo = mock(Demo.class);
  demo.getStudentList();

}

**我让学生将List对象设置为null ** 客户是第三方服务,它是抽象的

//我应该如何在Java中模拟Future列表,这是正确的方法吗?

5 个答案:

答案 0 :(得分:1)

一旦模拟了Future类,就需要对其进行存根处理,以返回模拟列表对象,如下所示:

Future future = Mockito.mock(Future.class);
Mockito.when(future.get()).thenReturn(new ArrayList<>());

然后,您可以将未来对象验证为:

assertTrue(future.get() instanceof List);
assertTrue(((List) future.get()).isEmpty());

在您的情况下,将是这样的:

    @Test
    public void testData(){
        Client client = ClientFactory.getInstance(); // make sure client is mock

        // mock future and stub it
        Future mockFuture = mock(Future.class);
        List<Student> students = new ArrayList<>();
        when(mockFuture.get()).thenReturn(students);

        // mock stub the client
        when(client.getAsyncData()).thenReturn(mockFuture);

        // verify
        // . . .
    }

答案 1 :(得分:1)

尝试将已初始化的学生对象的列表作为列表返回,并将anyInt()或anyString()作为get()方法的参数传递。

请让我知道以下解决方案是否对您有用,否则请发布错误日志:

Future<List<Student>> mockFuture = Mockito.mock(Future.class);
when(client.getAsyncData()).thenReturn(mockFuture);
when(mockFuture.get(anyInt(), any())
.thenReturn(asList(new Student(21, "A"), new Student(22, "B")));

或者您可以尝试使用CompletableFuture创建已经完成的Future>。

when(mockFuture.get(anyInt(), any()))
.thenReturn(CompletableFuture.completedFuture(Arrays.asList(new Student(21, "A"), new Student(22, "B"))));

答案 2 :(得分:0)

请告诉我以下解决方案是否对您有效,或者您需要任何进一步的帮助/说明

//sugeestion: add an access modifier for the member variables
class Student{
int age;
String name;
}

class Demo{

public void getStudentList() {
Future<List<Student>> future = client.getAsyncData();
 }
}


class StudentTest{

  @Test
  public testData(){
/*Since its a Unit test case we must mock the other Object behavior to keep things simple and focused*/
  Client client = Mockito.spy(ClientFactory.getInstance());
  Future<List<Student>> mockFuture = mock(Future.class);
  when(client.getAsyncData()).thenReturn(mockFuture);
}

答案 3 :(得分:0)

如果您在此处不需要任何超时(根据您的代码也不需要), 您可以省略模拟并返回仅在java8中添加的completedFuture。

  List<Student> students = new ArrayList();
  Client client = ClientFactory.getInstance();
  Future<List<Student>> mockFuture = CompletableFuture.completedFuture(students);
  when(client.getAsyncData()).thenReturn(mockFuture);

答案 4 :(得分:0)

您已经创建了Student对象,并将其作为List实现的一部分,其中行List students = new ArrayList(),但尚未将值传递给该对象。在您的结构中,您可以添加学生成员,例如students.add(“ Rat”,“ 30”),这将创建一个具有值的对象,以便您可以进行测试。之所以返回NUll,是因为JUnit测试只是在说:“嘿,我没有要测试的东西,因为List实现中的对象为空”