使用Robolectric 2.3-SNAPSHOT,我想测试一个在后台执行请求的对象。为了隔离它,我试图模仿返回的HttpResponse,在投入几个小时后没有成功。
我创建了一个任何人都可以克隆的项目。模拟运行 ./ gradlew check https://github.com/Maragues/RobolectricDummyProject(git clone https://github.com/Maragues/RobolectricDummyProject.git)
我试过
Robolectric.setDefaultHttpResponse(200,“my_mocked_word”);
MockWebServer(https://code.google.com/p/mockwebserver/)
但测试失败是因为他们查询了真实的网址
private static final String MOCKED_WORD = "MOCKED";
@Test
public void mockedRequestUsingMockServer() throws Exception {
mMockWebServer.enqueue(new MockResponse().setBody(MOCKED_WORD));
mMockWebServer.play();
Robolectric.getFakeHttpLayer().interceptHttpRequests(false);
Robolectric.getFakeHttpLayer().interceptResponseContent(false);
String result = request.loadDataFromNetwork();
assertEquals(MOCKED_WORD, result);
}
@Test
public void mockedRequestUsingRobolectric() throws Exception {
Robolectric.setDefaultHttpResponse(200, MOCKED_WORD);
String result = request.loadDataFromNetwork();
assertEquals(MOCKED_WORD, result);
}
执行请求的代码
public String loadDataFromNetwork() throws Exception {
// With Uri.Builder class we can build our url is a safe manner
Uri.Builder uriBuilder = Uri.parse("http://robospice-sample.appspot.com/reverse").buildUpon();
uriBuilder.appendQueryParameter("word", word);
String url = uriBuilder.build().toString();
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url)
.openConnection();
String result = IOUtils.toString(urlConnection.getInputStream());
urlConnection.disconnect();
return result;
}
可能相关的问题
答案 0 :(得分:4)
您正在禁用Roboelectric的HTTP层,因此您正在使用真正的HTTP层。这意味着在你的测试中没有聪明的魔法发生:当你发送一个HTTP请求时,它真的会上网(正如你所看到的那样)。
MockWebServer不会停止此操作。它只是在本地设置一个Web服务器,您的测试可以连接到该服务器。
因此,要解决此问题,您需要停止尝试连接到真实服务器,而是连接到模拟服务器。为此,您需要在请求中注入/设置URL。
@Test
public void mockedRequestUsingMockServer() throws Exception {
mMockWebServer = new MockWebServer();
mMockWebServer.play();
mMockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(MOCKED_WORD));
request.myUrl = mMockWebServer.getUrl("/");
String result = request.loadDataFromNetwork();
assertEquals(MOCKED_WORD, result);
mMockWebServer.shutdown();
}
答案 1 :(得分:1)
事实证明,Robolectric的FakeHttpLayer仅适用于Apache的HttpClient,这对于大于Froyo的版本非常不鼓励。摘自Robolectric's Google Group
话虽如此,HttpUrlConnection的使用会给你带来麻烦。我尽可能尝试使用Android的HttpClient实现,因为Robolectric拦截了对该库的所有调用,并允许您设置对HTTP调用的预设响应。我们正在考虑为HttpUrlConnection做同样的事情,虽然目前还不清楚何时会发生这种情况。
除此之外,单元测试不需要模拟HTTP层。我的方法从一开始就错了。
答案 2 :(得分:1)
你可以试试这个(参考:https://github.com/square/okhttp/tree/master/mockwebserver)。
// Create a MockWebServer. These are lean enough that you can create a new
// instance for every unit test.
MockWebServer server = new MockWebServer();
// Schedule some responses.
server.enqueue(new MockResponse().setBody("it's all cool"));
// Start the server.
server.play();
// Ask the server for its URL. You'll need this to make HTTP requests.
//Http is my own http executor.
Http.Response response = http.get(server.getUrl("/"));
然后,您可以将回复与server.enqueue(new MockResponse().setBody("it's all cool"));
MockWebServer是okhttp https://github.com/square/okhttp/tree/master/mockwebserver的一部分。 android 4.4中的URLConnectionImpl已经changed from defaultHttpClient to Okhttp。