Android 单元测试之Roboletric RxJava、Retrofit、访问真实网络、虚拟服务器
Android 单元测试之JUnit和Mockito
Android 单元测试之Roboletric 环境配置
Android 单元测试之Roboletric的简单使用
Android 单元测试之Roboletric RxJava、Retrofit、访问真实网络、虚拟服务器
Android 单元测试之Espresso - Google官方UI测试框架
添加依赖
android {
...
configurations.all {
resolutionStrategy {
force 'com.android.support:support-annotations:24.1.1'
}
}
}
dependencies {
...
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.1.2'
testCompile 'org.khronos:opengl-api:gl1.1-android-2.1_r1'
testCompile 'org.hamcrest:hamcrest-all:1.3'
testCompile 'org.mockito:mockito-all:2.0.2-beta'
testCompile 'org.robolectric:shadows-httpclient:3.0'
testCompile 'com.squareup.okhttp3:mockwebserver:3.4.1'
compile 'org.robolectric:shadows-core-v23:3.1.2'
compile 'com.android.support:appcompat-v7:24.1.1'
compile 'io.reactivex:rxjava:1.1.9'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'com.android.support:support-annotations:24.1.1'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
compile 'com.squareup.retrofit2:retrofit-converters:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
}
RxJava测试
RxJava专门提供了一个TestSubscriber,方便测试
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class MockitoTest {
@Test
public void MocksTest() {
TestSubscriber<Bean> testSubscriber = new TestSubscriber<>();
getMocks().subscribe(testSubscriber);
assertThat(testSubscriber.getOnNextEvents().size(), is(3));
}
private Observable<Bean> getMocks() {
return Observable.just(new Bean(), new Bean(), new Bean());
}
}
虚拟服务器之FakeHttp
@Test
public void reposTest1() throws IOException {
String mockJsonResult =
"[{\"id\":19669199,\"name....省略}]";
FakeHttp.addPendingHttpResponse(200, mockJsonResult);
HttpGet httpGet = new HttpGet("http://www.baidu.com");
HttpResponse httpResponse = new DefaultHttpClient().execute(httpGet);
String result = EntityUtils.toString(httpResponse.getEntity());
System.out.print(result);
assertThat(result, is(mockJsonResult));
}
虚拟服务器之MockWebServer
@Test
public void MockServerTest() throws IOException, InterruptedException {
// 1. 创建服务器
MockWebServer server = new MockWebServer();
// 2. 添加预置的响应,响应会按照先进先出的顺序依次返回
server.enqueue(new MockResponse().setBody("i am ethanco"));
server.enqueue(new MockResponse().setResponseCode(404).setBody("not found")); //按顺序返回,即如果请求两次,第二次就会返回这个
server.enqueue(new MockResponse().setResponseCode(503).setBody("hello, world!")); //第三次返回这个
// 3. 启动服务器
server.start();
// 4. 获取请求 url,不能使用普通的 URL,一定要使用 server.url() 返回的 URL,不然没法进入 Mock 服务器
HttpUrl baseUrl = server.url("/reg1");
//5.发送请求
URL url = new URL(baseUrl.url().toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
assertEquals(200, conn.getResponseCode());
InputStream is = conn.getInputStream();
//把流转化为文本信息 String
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
String result = bos.toString();
bos.close();
is.close();
System.out.println(result);
// server.takeRequest() 是一个阻塞操作,直到接收到请求
RecordedRequest request1 = server.takeRequest();
//这里可以查看服务器获取的请求信息,可以查看 http 报文头之类的协议信息
assertEquals("/reg1", request1.getPath());
server.shutdown();
}
FakeHttp和MockWebServer都可以模拟服务器进行测试,从而提高开发速度。但推荐使用MockWebServer,因为FakeHttp只支持AndroidHttpClient,而MockWebServer支持所有的网络访问库,包括Retrofit。
通过真实网络访问数据
在此处使用Retrofit
public interface APIService {
@GET("/users/{user}/repos")
public Call<List<Repo>> listRepos(@Path("user") String user);
@GET("/users/{user}/repos")
public Observable<List<Repo>> listRepos2Observable(@Path("user") String user);
}
访问网络
@Before
public void setUp() {
apiService = RetrofitFactory.getInstance().createRetrofit("https://api.github.com").create(APIService.class);
}
@Test
public void reposTest2() {
List<Repo> list = null;
try {
list = apiService.listRepos("devinshine").execute().body();
} catch (IOException e) {
e.printStackTrace();
}
assertThat(list.size(), is(not(0)));
System.out.print(list.size());
}
@Test
public void reposTestByObservable() {
int size = apiService.listRepos2Observable("devinshine")
.flatMap(Observable::from)
.count()
.toBlocking()
.single();
assertThat(size, is(not(0)));
System.out.print(size);
}
可能出现的错误
java.lang.AssertionError
解决方法
设置@Config(sdk = 23)
具体请看 issues
其他
在Android中有assertj-android
是一组面向测试Android AssertJ断言。这个库的扩展于AssertJ,旨在使其更容易测试 Android。
可以用这个代替原生的assert