使用Robolectrics和Mockito模拟/存根函数调用发出http请求,但它不起作用

时间:2015-11-07 11:15:45

标签: java android junit mockito robolectric

我使用RobolectricsMockito来测试android项目,我模拟了一个使http请求后端的方法。

http客户端的实际类:

public class MyHttpClient {
 ...
 public int sendDataToBackend(Object data) {
    return doHttpRequest(data);
 }

 private int doHttpRequest() {
    System.out.println("start http request ...");
    ...
    return responseCode;
 }
}

以上MyHttpClient类用于MyService类:

public class MyService {
 ...
 public void notifyBackend(Object data) {
   MyHttpClient client = new MyHttpClient();
   int responseCode = client.sendDataToBackend(data);
   ...
 }
}

我单元测试MyService

@RunWith(RobolectricTestRunner.class)
public class MyServiceTest {
  @Mock
  private MyHttpClient client;

  @InjectMocks
  private MyService service;

  @Before
  public void setUp() {
    client = new MyHttpClient();
    service = new MyService();
  }

  @Test
  public void testNotifyBackend() {
    Object data = generateData();
    //stub method call
    when(client.sendDataToBackend(data)).thenReturn(200);

    service.notifyBackend(data);
  }
}

我运行上面的单元测试,我预计sendDataToBackend()类中的MyHttpClient函数体不会被执行,因为我们已经模拟/存根函数返回200,但是我仍然看到System.out.print()消息:

start http request ...

来自MyHttpClient#doHttpRequest(),为什么?

(我的测试失败了,因为它试图做真正的http请求)

======更新=======

此外,我还认为我不应该在client = new MyHttpClientsetUp(),因为client应该被嘲笑,但是当我尝试时:

@Before
public void setUp() {
  service = new MyService();
}

我在中获得了 NullPointerException

when(client.sendDataToBackend(data)).thenReturn(200);

这就是我在client = new MyHttpClient中添加setUp()的原因。我还想问一下为什么我得到 NullPointerException ,如果client被模拟了?

2 个答案:

答案 0 :(得分:2)

不是在服务中创建客户端,而是通过构造函数提供它:

class MyService {
   final MyHttpClient client;
   MyService(MyHttpClient client) { this.client = client; }
}

然后,在您的测试中,将模拟客户端提供给它。它就这么简单。

@RunWith(MockitoJunitRunner.class)
public class MyServiceTest {
  @Mock
  private MyHttpClient client;

  private MyService service;

  @Before
  public void setUp() {
    service = new MyService(client);
  }
  ....    
}

答案 1 :(得分:0)

将您的方法更改为:

@Before
public void setUp() {
  service = new MyService();
}

你嘲笑它,对。但是,您通过为client分配MyHttpClient新实例来覆盖该实例。