关于android单元测试的一切

2017-03-15  本文已影响62人  JustinBetter

介绍

Junit4

java测试框架

testCompile 'junit:junit:4.12'
@Before
@Test
(expected = IllegalArgumentException.class) 验证是否抛该异常
@After
@Ignore 跑所有测试方法忽略该方法

除了在AndroidStudio里面运行,你还可以在命令行通过gradle testDebugUnitTest,或者是gradle testReleaseUnitTest,分别运行debug和release版本的unit testing

Mockito的使用

repositories { jcenter() }
dependencies {
      testCompile "org.mockito:mockito-core:
}
  1. 验证方法调用:
    Mockito.verify(objectToVerify,Mockito.times(3)).methodToVerify(Mockito.anyString());
  1. 设定返回值,方便测试:
    Mockito.when(mockObject.targetMethod(args)).thenReturn(desiredReturnValue);
  2. 执行特定动作,如访问网络数据
Mockito.doAnswer(desiredAnswer).when(mockObject).targetMethod(args);
Mockito.doAnswer(new Answer() {
   @Override
   public Object answer(InvocationOnMock invocation) throws Throwable {
       //这里可以获得传给performLogin的参数
       Object[] arguments = invocation.getArguments();

       //callback是第三个参数
       NetworkCallback callback = (NetworkCallback) arguments[2];

       callback.onFailure(500, "Server error");
       return 500;
   }
}).when(mockUserManager).performLogin(anyString(), anyString(), any(NetworkCallback.class));

ps: Mockito.spy与mock的唯一区别就是默认行为不一样:spy对象的方法默认调用真实的逻辑,mock对象的方法默认什么都不做,或直接返回默认值。

dagger2

能不用就不用!

buildscript {
    ...
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.2'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        //添加apt插件
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}

...
//应用apt插件
apply plugin: 'com.neenbedankt.android-apt'

...

dependencies {
    ...
    //引入dagger2
    compile 'com.google.dagger:dagger:2.4'
    apt 'com.google.dagger:dagger-compiler:2.4'
    //java注解
    provided 'org.glassfish:javax.annotation:10.0-b28'
}

client --> Component(工厂管理员)-->Module(生产依赖的工厂)-->Dependency

//需要测试
public class LoginActivity extends AppCompatActivity {
    @Inject
    LoginPresenter mLoginPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ComponentHolder.getAppComponent().inject(this);

        findViewById(R.id.login).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                String username = ((EditText) findViewById(R.id.username)).getText().toString();
                String password = ((EditText) findViewById(R.id.password)).getText().toString();

                mLoginPresenter.login(username, password);
            }
        });
    }
}
//测试
public class DaggerUtils {
   public static final AppModule appModule = spy(new AppModule(RuntimeEnvironment.application));

   public static void setupDagger() {
       AppComponent appComponent = DaggerAppComponent.builder().appModule(appModule).build();
       ComponentHolder.setAppComponent(appComponent);
   }
}
//-------
@RunWith(RobolectricGradleTestRunner.class) //Robolectric相关,看不懂的话忽略
@Config(constants = BuildConfig.class, sdk = 21) //同上
public class LoginActivityTest {

    @Test
    public void testActivityStart() {
        @Test
        public void testActivityStart() {
            DaggerUtils.setupDagger();

            LoginPresenter mockLoginPresenter = mock(LoginPresenter.class);  
            Mockito.when(DaggerUtils.appModule.provideLoginPresenter(any(UserManager.class), any(PasswordValidator.class))).thenReturn(mockLoginPresenter);  

            LoginActivity loginActivity = Robolectric.setupActivity(LoginActivity.class);
            ((EditText) loginActivity.findViewById(R.id.username)).setText("xiaochuang");
            ((EditText) loginActivity.findViewById(R.id.password)).setText("xiaochuang is handsome");
            loginActivity.findViewById(R.id.login).performClick();    
            verify(mockLoginPresenter).login("xiaochuang", "xiaochuang is handsome");  //pass!
        }
    }
}

Robolectric使用

Robolectric就是一个能够让我们在JVM上跑测试时够调用安卓的类的框架

testCompile 'junit:junit:4.12'
testCompile "org.robolectric:robolectric:3.2.1"```
- api

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class MainActivityTest {
@Test
public void testMainActivity() {
MainActivity mainActivity = Robolectric.setupActivity(MainActivity.class);
mainActivity.findViewById(R.id.textView1).performClick();

    Intent expectedIntent = new Intent(mainActivity, SecondActivity.class);  
    ShadowActivity shadowActivity = Shadows.shadowOf(mainActivity);  
    Intent actualIntent = shadowActivity.getNextStartedActivity();  
    Assert.assertEquals(expectedIntent, actualIntent);  
}  

}


- 参考: http://chriszou.com/2016/06/07/android-unit-testing-everything-you-need-to-know.html
上一篇下一篇

猜你喜欢

热点阅读