Android 单元测试(junit、mockito、robolectric)

时间:2022-11-22 14:05:09

1、运用JUnit4 进行单元测试

首先在工程的 src 文件夹内创建 test 和 test/java 文件夹。

打开工程的 build.gradle(Module:app)文件,添加JUnit4依赖,点击Gradle sync按钮。

build.gradle

 dependencies {
testCompile 'junit:junit:4.12'
}

(1)新建被测类:

 public class Calculator {

     public double sum(double a, double b){
// 假设先返回结果0
return 0;
}
}

(2)新建测试类:


import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class CalculatorTest {

    private Calculator mCalculator;

    @Before
public void setUp() throws Exception {
mCalculator = new Calculator();
} @Test
public void testSum() throws Exception {
//断言:1+1 = 2
assertEquals(mCalculator.sum(1d, 1d), 2d);
}
}

这时候 右键 - testSum()方法,选择选择Run > testRun , 也可以通过命令行运行测试,在工程目录内输入:

 ./gradlew test

这时测试因为我写被测类的时候,返回的是0,所以跟期望的值不一样,就会失败。

这时,我们修改下Calculator.java的函数:

 public double sum(double a, double b){
return a + b;
}

保存,这时候再运行测试,成功,跟期望值一样。

总结:位于src/tests目录下的测试是运行在本地电脑Java虚拟机上的单元测试。

编写测试,实现功能使测试通过,然后再添加更多的测试,这种工作方式使快速迭代成为可能,我们称之为测试驱动开发

2、使用Mockito等mocking框架来mock测试。

Mock:

mock对象就是在调试期间用来作为真实对象的替代品。

mock测试就是在测试过程中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试。

打开工程的 build.gradle(Module:app)文件,添加Mockito依赖,点击Gradle sync按钮。

build.gradle

 dependencies {
// 单元测试
testCompile 'org.mockito:mockito-all:2.0.2-beta'
testCompile 'junit:junit:4.12'
}

关于mokito的使用,官网已经给出很详细了。我这里主要想记录下主要用到的。对于mvp架构下,测试presenter返回到view的数据,是否正确。

配合mvp模式下,利用本地json,模仿网络请求,进行模拟数据,查看presenter 处理逻辑是否正确。

public class PresenterTest {

    @Mock
Repository repository; // 网络请求
@Mock
View view; // view PresenterImpl presenter; @Before
public void setUp() throws Exception {
// 如果有使用到rxjava,可以在这里处理rxjava变成同步执行
MockitoAnnotations.initMocks(this); presenter = new PresenterImpl(view, repository);
} @Test
public void getOrderList() throws Exception{
String json = readAssetsJSON("get_list.json").optString("data");
List<ViewModel> list = JSON.parseArray(json, ViewModel.class); when(repository.getList(1)).thenReturn(Observable.just(list));
presenter.getList(1); ArgumentCaptor<ArrayList> captor = ArgumentCaptor.forClass(ArrayList.class);
verify(presenter.getView()).onGetDataByFinish(captor.capture()); List<ViewModel> viewModels = captor.getValue(); assertEquals(list.size(), viewModels.size());
}
}

get_list.json 是放到 src/test下的assets 目录下,这个目录在:打开工程的 build.gradle(Module:app)文件,android节点下的sourceSets节点下,配置下:

 sourceSets {
main {
.....
} test {
java.srcDirs = [ 'src/test/java']
}
}

其他的用法:参考下官方就行,因为官网是英文的,看不懂的,还可以前往:Mockito 中文文档

3、使用Robolectric 

Robolectric 是一个针对于Android SDK 的单元测试框架,使用它可以测试驱动你的Android应用程序的开发。测试用例只需要在JVM基础上就能运行起来。

打开工程的 build.gradle(Module:app)文件,添加Robolectric依赖,点击Gradle sync按钮。

build.gradle

 dependencies {
// 单元测试
testCompile 'org.robolectric:robolectric:3.1-rc1'
testCompile 'org.mockito:mockito-all:2.0.2-beta'
testCompile 'junit:junit:4.12'
}

1、创建一个WelcomeActivity, 点击登录,跳转到登录页面。

布局文件:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
    android:layout_height="match_parent">  
    <Button 
        android:id="@+id/btn_login"
android:text="click the btn" 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>  
</LinearLayout> 

Activity:

public class WelcomeActivity extends Activity {  
    @Override 
    protected void onCreate(Bundle savedInstanceState) {       
   super.onCreate(savedInstanceState); 
        setContentView(R.layout.welcome_activity);  
        final View button = findViewById(R.id.btn_login); 
        button.setOnClickListener(new View.OnClickListener() {  
            @Override 
            public void onClick(View view) { 
                startActivity(new Intent(getContext(), LoginActivity.class));     
      }      
    });
     }
 }

测试的是:当用户点击登陆按钮后,我们启动了正常的intent。

由于Robolectric只是一个模拟的单元测试框架,LoginActivity并不会真正的启动,但是我们可以检查是否准确的发出了WelcomActivity的intent。

 @RunWith(RobolectricTestRunner.class) 
public class WelcomeActivityTest {  
    @Test 
    public void clickingLogin_shouldStartLoginActivity() { 
        WelcomeActivity activity = Robolectric.setupActivity(WelcomeActivity.class);       
      activity.findViewById(R.id.btn_login).performClick();  
        Intent expectedIntent = new Intent(activity, WelcomeActivity.class);         
     assertThat(shadowOf(activity).getNextStartedActivity()).isEqualTo(expectedIntent);  
   } 

判断点击后textview 文本变化是否正常等:

 @RunWith(RobolectricTestRunner.class)
public class WelcomeActivityTest { @Test
public void clickLoginButton() throws Exception {
Activity activity = Robolectric.buildActivity(WelcomeActivity.class).create().get(); Button btn_login = (Button) activity.findViewById(R.id.btn_login);
TextView tv_result = (TextView) activity.findViewById(R.id.tv_result); btn_login.performClick();
String resultsText = tv_result.getText().toString();
assertThat(resultsText, equalTo("Click the login button"));
}
}

对于控制activity的生命周期,Robolectric 2.2版本以后增加了控制activity方法:

 Activity activity = Robolectric.buildActivity(WelcomeActivity.class).create().get();

这会创建一个WelcomeActivity,并且已经调用了onCreate()。

(1)检查一些在onCreate()和onResume()之间发生的事件:

 ActivityController controller = 
          Robolectric.buildActivity(WelcomeActivity.class).create().start(); 
Activity activity = controller.get(); 
// assert that something hasn't happened 
activityController.resume(); 

(2)完整的生命周期:

 Activity activity = 
      Robolectric.buildActivity(WelcomeActivity.class).create().start().resume().visible().get(); 

(3)使用intent 来启动activity:

 Intent intent = new Intent(Intent.ACTION_VIEW); 
Activity activity = 
    Robolectric.buildActivity(WelcomeActivity.class).withIntent(intent).create().get();

(4)保存状态:

1 Bundle savedInstanceState = new Bundle(); 
2 savedInstanceState.putExtra("user_age", "18");
3 savedInstanceState.putExtra("user_name", "jay");
4 Activity activity = Robolectric.buildActivity(WelcomeActivity.class).create() 
5        .restoreInstanceState(savedInstanceState).get(); 

Android 单元测试(junit、mockito、robolectric)的更多相关文章

  1. Android&colon;单元测试Junit的配置

    在实际开发中,开发android软件的过程需要不断地进行测试.而使用Junit测试框架,侧是正规Android开发的必用技术,在Junit中可以得到组件,可以模拟发送事件和检测程序处理的正确性.... ...

  2. Android单元测试Junit (一)

    1.在eclips中建立一个Android工程,具体信息如下: 2.配置单元测试环境,打开AndroidManifest.xml,具体代码如下所示: <?xml version="1. ...

  3. Android 单元测试Junit

  4. Android单元测试

    安卓单元测试总结文章,目测主要会cover以下的主题: 什么是单元测试 为什么要做单元测试 JUnit Mockito Robolectric Dagger2 一个具体的app例子实践 神秘的bonu ...

  5. Android单元测试&colon; 首先,从是什么开始

    Android单元测试: 首先,从是什么开始 http://chriszou.com/2016/04/13/android-unit-testing-start-from-what.html 这是一系 ...

  6. Android studio下gradle Robolectric单元测试配置

    android studio下gradle Robolectric单元测试配置 1.Robolectric Robolectric是一个基于junit之上的单元测试框架.它并不依赖于Android提供 ...

  7. JUnit &plus; Mockito 单元测试(二)

    摘自: http://blog.csdn.net/zhangxin09/article/details/42422643 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 入门 ...

  8. JUnit &plus; Mockito 单元测试(二)&lpar;good&rpar;

    import org.junit.Test; import org.mockito.Matchers; import org.mockito.Mockito; import java.util.Lis ...

  9. 阿里知识储备之二——junit学习以及android单元测试

    一,junit框架 http://blog.csdn.net/afeilxc/article/details/6218908 详细见这篇博客 juit目前已经可以和maven项目进行集成和测试,而且貌 ...

随机推荐

  1. &lbrack;转&rsqb;使用 HTML5 IndexedDB API

    本地数据持久性提高了 Web 应用程序可访问性和移动应用程序响应能力 索引数据库 (IndexedDB) API(作为 HTML5 的一部分)对创建具有丰富本地存储数据的数据密集型的离线 HTML5 ...

  2. spfa的SLF优化

    spfa的SLF优化就是small label first 优化,当加入一个新点v的时候如果此时的dis[v]比队首dis[q.front()]还要小的话,就把v点加入到队首,否则把他加入到队尾,因为 ...

  3. Oracle中instr 函数的详解

    INSTR    (源字符串, 目标字符串, 起始位置, 匹配序号)    在Oracle/PLSQL中,instr函数返回要截取的字符串在源字符串中的位置.只检索一次,就是说从字符的开始    到字 ...

  4. HDU 4643 GSM 算术几何

    当火车处在换基站的临界点时,它到某两基站的距离相等.因此换基站的位置一定在某两个基站的中垂线上, 我们预处理出任意两基站之间的中垂线,对于每次询问,求询问线段与所有中垂线的交点. 检验这些交点是否满足 ...

  5. NodeJs使用Mysql模块实现事务处理

    依赖模块: 1. mysql:https://github.com/felixge/node-mysql npm install mysql --save 2. async:https://githu ...

  6. mysql source命令导入sql文件效率分析和索引整理

    Query OK, 24918 rows affected (0.90 sec)Records: 24918  Duplicates: 0  Warnings: 0 Query OK, 24923 r ...

  7. web实现QQ第三方登录

    开放平台-web实现QQ第三方登录   应用场景     web应用通过QQ登录授权实现第三方登录.   操作步骤     1  注册成为QQ互联平台开发者,http://connect.qq.com ...

  8. 【一天一道LeetCode】&num;349&period; Intersection of Two Arrays

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given t ...

  9. APP支付(&period;NET版)

    ---恢复内容开始--- APP支付(.NET版) 一.   支付宝支付 1. 有一个支付账号,在蚂蚁金服开放平台中登录账号→选择“管理中心”→在“开发者中心”下选择“网页&移动应用”→然后按 ...

  10. windows程序设计 加载位图图片

    现在网上随便下个jpg图片,用windows自带的画图工具打开,点击画图工具左上角,文件->另存为->选择bmp,点击保存,保存好后,就得到一张位图了. 得到的位图,位图的内存比原图片jp ...