美文网首页
Android 使Android Studio单元测试(以mv

Android 使Android Studio单元测试(以mv

作者: SmallWalnutBG | 来源:发表于2020-10-16 17:24 被阅读0次

    第一步:build.gradle文件添加测试相关依赖

    dependencies {

        testImplementation 'junit:junit:4.12'

        testImplementation 'org.mockito:mockito-core:2.19.0'

        testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0'//mock()

        testImplementation 'org.mockito:mockito-inline:2.13.0'//适配单元测试时,不能调用final类

    ...

    }

    第二步新建测试类(项目中存在的类)

    BasePresenter:

    packagecom.example.testabstractclassBasePresenter{protectedvarview: V? =nullfunattachView(view:V){this.view = view  }fundetachView(){this.view =null}}

    Recipe:

    packagecom.example.testclassRecipe(varid : String ="",vartitle :String ="",varimageUrl : String ="",varsourceUrl : String ="",varisFavorited :Boolean=false)

    RecipeRepository:

    packagecom.example.testinterfaceRecipeRepository{funaddFavorite(item:Recipe)funremoveFavorite(item:Recipe)fungetFavoriteRecipes(): ListfungetRecipes(query:String, callback:RepositoryCallback>)}interfaceRepositoryCallback{funonSuccess(t:T?)funonError()}

    SearchResultsPresenter:

    packagecom.example.test/**

    * JunitTestClass

    */classSearchResultsPresenter(privatevalrepository: RecipeRepository) :    BasePresenter() {privatevarrecipes: List? =nullfunsearch(query:String){    view?.showLoading()    repository.getRecipes(query,object: RepositoryCallback> {overridefunonSuccess(recipes:List?){this@SearchResultsPresenter.recipes = recipesif(recipes !=null&& recipes.isNotEmpty()) {          view?.showRecipes(recipes)        }else{          view?.showEmptyRecipes()        }      }overridefunonError(){        view?.showError()      }    })  }funaddFavorite(recipe:Recipe){    recipe.isFavorited =truerepository.addFavorite(recipe)valrecipeIndex = recipes?.indexOf(recipe)if(recipeIndex !=null) {      view?.refreshFavoriteStatus(recipeIndex)    }  }funremoveFavorite(recipe:Recipe){    repository.removeFavorite(recipe)    recipe.isFavorited =falsevalrecipeIndex = recipes?.indexOf(recipe)if(recipeIndex !=null) {      view?.refreshFavoriteStatus(recipeIndex)    }  }interfaceView{funshowLoading()funshowRecipes(recipes:List)funshowEmptyRecipes()funshowError()funrefreshFavoriteStatus(recipeIndex:Int)}}

    第三步:给presenter新建测试类

    1>、windows快捷键:ctrl+shift+T(也可鼠标右键->go to->Test);

    2>、接着有测试类会让你选择,没有的->create new test...;

    3>​

    4>新建成功​

    第四步:编写测试方法

    1>verify方法(@Before将在@Test等方法之前调用)

    classSearchResultsPresenterTest{privatelateinitvarrepository: RecipeRepositoryprivatelateinitvarpresenter: SearchResultsPresenterprivatelateinitvarview: SearchResultsPresenter.View@Before//最先调用(初始化)funsetup(){        repository = mock()        view = mock()        presenter = SearchResultsPresenter(repository)        presenter.attachView(view)    }@Testfunsearch_callsShowLoading(){        presenter.search("eggs")//        verify(view).showLoading()//验证搜索时showLoading会不会被调用到verify(view).showEmptyRecipes()//验证showEmptyRecipes会不会被调用到//        verify(view).showRecipes(mock())//验证showRecipes会不会被调用到}}

    如果verify方法验证了这次运行未调用此方法,运行后将会抛出错误,便于我们验证是否运行后调用该方法(如果调用了,日志没有反应)

    ​​

    同时刚才我们的coverage运行结果可以直接查看方法被调用的情况

    2、doAnswer方法(插桩):

    @Testfunsearch_callShowRecipes(){valrecipe = Recipe("id","title","imageUrl","sourceUrl",false)valrecipes = listOf(recipe)        doAnswer {//执行相应的方法(getRecipes)并拿到回调(Stubbing--插桩)valcallback: RepositoryCallback> = it.getArgument(1)//            callback.onSuccess(recipes)//此时以下的verify将会全部通过callback.onError()//这里也可以用onError()方法验证(此时下面的verify(view).showRecipes(eq(recipes))将会抛出错误)}.whenever(repository).getRecipes(eq("eggs"), any())        presenter.search("eggs")        verify(repository).getRecipes(eq("eggs"), any())        verify(view).showRecipes(eq(recipes))    }

    通过doAnswer方法和verify方法,我们可以验证代码是否正确调用了正确的方法(行为验证)

    3:Assert 方法:

    @TestfunaddFavorite_shouldUpdateRecipeStatus(){valrecipe = Recipe("id","title","imageUrl","sourceUrl",false)        presenter.addFavorite(recipe)//状态验证,assertThat(T actual, Matcher<? super T> matcher)左边为待验证的字段,右边为匹配器,// is是kotlin关键字,所以'is'。如果验证字段不同将会抛出错误。Assert.assertThat(recipe.isFavorited, CoreMatchers.`is`(false))    }

    状态验证,assertThat(T actual, Matcher<? super T> matcher)左边为待验证的字段,右边为匹配器,is是kotlin关键字,所以'is';

    @TestfunremoveFavorite_shouldUpdateRecipeStatus(){valrecipe = Recipe("id","title","imageUrl","sourceUrl",true)        presenter.removeFavorite(recipe)        Assert.assertThat(recipe.isFavorited, CoreMatchers.`is`(false))    }

    参考连接:

    https://juejin.im/post/6844903848272723975#heading-14

    相关文章

      网友评论

          本文标题:Android 使Android Studio单元测试(以mv

          本文链接:https://www.haomeiwen.com/subject/kettmktx.html