Mockito的简单实践

一、简要概念:

1.Mock的概念:mock就是创建一个类的虚假的对象,在测试环境中,用来替换掉真实的对象
2.目的:
    ①验证这个对象的某些方法的调用情况,调用了多少次,参数是什么等等 
    ②可以随时指定mock对象的某个方法返回什么样的值,或执行什么样的动作。
    Mockito.verify(mockUserManager, Mockito.times(3)).performLogin(...);
    Mockito.when(mock.verifyPassword(anyString())).thenReturn(true);

 3.要使用mock,一般需要使用mock框架,目前安卓最常用的有两个,Mockito和JMockit。两者的区别是,前者不能mock static method和final class、final method,后者可以。

二、环境配置:

      testCompile "org.mockito:mockito-core:1.10.19"

三、测试demo,一切尽在代码中

 class LoginPresenter {
    private String userName;

    LoginView view = new LoginView();


    public void login(String name, String pwd){
      view.performLogin( name, pwd );

    }

    public String getUserName(){
        return userName;
    }
    public void setUserName(String name){
        this.userName = name;
    }

    public String getServerData (String param){
        return  "服务器数据";
    }


    public void setView( LoginView view){
        this.view = view;
    }

     void privateMethod(String name, String pwd){
        view.performLogin( name, pwd );
    }

    public void buttonClickCallback(){
        view.setOnFcButtonClickListener(new LoginView.OnFcButtonClickListener() {
            @Override
            public void onFcButtonClick(int n) {
                if (n == 1) {
                    view.performLogin("fc","111");
                }
            }
        });

    }
public class LoginView {

    public interface OnFcButtonClickListener {
        void onFcButtonClick(int n);
    }
    private OnFcButtonClickListener onfcButtonClickListener;

    public void setOnFcButtonClickListener(OnFcButtonClickListener listener){
        this.onfcButtonClickListener = listener;
    }

    public LoginView() {
    }

    public void performLogin(String name, String pwd){

    }

    public void buttonClickCallback(int n){
        onfcButtonClickListener.onFcButtonClick(n);
    }


}
mockito的用法的简单例子
public class LoginPresenterTest {
    private LoginView mockLoginView;
    private LoginPresenter presenter;

    @Before
    public void setUp() throws Exception {
        mockLoginView = Mockito.mock(LoginView.class);
        presenter = new LoginPresenter();
    }


    /**
     * 方法描述:测试 LoginPresenter的login()方法是否调用LoginView的performLogin()方法
     * 期待结果:被调用,且参数正常
     *
     * 注意:mock出来的对象并不会自动替换掉正式代码里面的对象,你必须要有某种方式把mock对象应用到正式代码里面
     *
     * @throws Exception
     */
    @Test
    public void login() throws Exception {
        presenter = new LoginPresenter();
        presenter.setView(mockLoginView);
        presenter.login("fc","111");
        Mockito.verify(mockLoginView).performLogin("fc","111");
//        Mockito.verify(mockLoginView).performLogin("大大","111");
    }


    /**
     * 方法描述:是否至少调用一次某个方法
     * 期待结果: 是
     *
     * @throws Exception
     */
    @Test
    public void login_atLeastOnce() throws Exception {
        presenter.setView(mockLoginView);
        presenter.login("fc","111");
        Mockito.verify(mockLoginView,Mockito.atLeastOnce()).performLogin("fc","111");
    }

    /**
     * 方法描述:测试是否调用了两次
     * 期待结果: 是
     *
     * @throws Exception
     */
    @Test
    public void login_twice() throws Exception {
        presenter.setView(mockLoginView);
        presenter.login("fc","111");
        presenter.login("fc","111");
        Mockito.verify(mockLoginView,Mockito.times(2)).performLogin("fc","111");
    }


    /**
     * 指定mock对象的某个方法返回特定的的值
     */
    @Test
    public void getServerData_Specify(){
        String value = "小小";
        LoginPresenter mockPresenter = Mockito.mock(LoginPresenter.class);
        Mockito.when(mockPresenter.getServerData(Mockito.anyString())).thenReturn(value);
        Assert.assertEquals(mockPresenter.getServerData("你好"),value);
    }

    /**
     * 调用一次返回不同的值
     */
    @Test
    public void getServerData_differValue(){
        String value = "ZhangSan";
        String secondValue = "LiSi";
        LoginPresenter mockPresenter = Mockito.mock(LoginPresenter.class);
        Mockito.when(mockPresenter.getServerData(Mockito.anyString())).thenReturn(value).thenReturn(secondValue);
        Assert.assertEquals(mockPresenter.getServerData("你好"),value);
        Assert.assertEquals(mockPresenter.getServerData("你好+1"),secondValue);
    }


    /**
     * mock和spy 的区别:
     * 使用Mock生成的类,所有方法都不是真实的方法,而且返回值都是NULL
     * 使用Spy生成的类,所有方法都是真实方法,返回值都是和真实方法一样的。
     *
     * @throws Exception
     */
    @Test
    public void getUserName() throws Exception{
//        LoginPresenter spyPresenter = Mockito.mock(LoginPresenter.class);
        LoginPresenter spyPresenter = Mockito.spy(LoginPresenter.class);
        spyPresenter.setUserName("fc");
        Assert.assertEquals("fc",spyPresenter.getUserName());

    }

    /**
     *  测试私有方法: 去掉private
     */
    @Test
    public void testPrivateMethod(){
        presenter = new LoginPresenter();
        presenter.setView(mockLoginView);
        presenter.privateMethod("fc","111");
        Mockito.verify(mockLoginView).performLogin("fc","111");
    }


    /**
     *  测试接口回调,异步方法:
     *  指定回调某种状态后,验证代码逻辑对不对
     */
    @Test
    public void testCallBack(){

        Mockito.doAnswer(new Answer() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                Object[] arguments = invocation.getArguments();
                LoginView.OnFcButtonClickListener listener = (LoginView.OnFcButtonClickListener) arguments[0];
                //模拟回调的状态  可以试试把1改为其他的值
                listener.onFcButtonClick(1);
                return null;
            }
        }).when(mockLoginView).setOnFcButtonClickListener(Mockito.any(LoginView.OnFcButtonClickListener.class));

        presenter.setView(mockLoginView);
        presenter.buttonClickCallback();
        Mockito.verify(mockLoginView).performLogin(Mockito.anyString(),Mockito.anyString());
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值