Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the method of android unit testing

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

Today, I would like to share with you the relevant knowledge of what the android unit testing method is, the content is detailed, the logic is clear, I believe most people still know too much about this knowledge, so share this article for your reference, I hope you can get something after reading this article, let's learn about it.

Text

First of all, let's start with the Model layer and explain in detail how a test project with 100% unit test coverage is established through specific code. Strictly speaking, the Model data layer is responsible for data loading and storage, and is isolated from the Android environment, so it does not need the support of Android SDK. Unit testing with 100% conditional branch coverage can be achieved by using Junit combined with Mockito. If the Model layer of the project is Android dependent, it may indicate that the code here needs to be refactored, which is part of the meaning of unit testing to make the code logic clearer. Another benefit of eliminating Android dependency in the Model layer is to make test case more efficient. Test case with android dependency takes up to 5 seconds to execute, but for a Model class that does not have Android dependency, the time to run all case can be reduced to milliseconds. Therefore, it is necessary to get rid of the Android dependency that is not needed in the Model layer.

Code

The Model layer test code is as follows:

RunWith (MockitoJUnitRunner.class) public classWeatherModelTest {privateWeatherModelmodel; @ Mock ApiServiceapi; @ Mock WeatherDataConvertconvertData; @ Mock WeatherRequestListenerlistener; private static finalStringJSON_ROOT_PATH= "/ json/"; privateStringjsonFullPath; privateWeatherDatanetData; privateMapqueryMap; @ Before public voidsetUp () {RxUnitTestTools.openRxTools (); model=newWeatherModel () } private voidinitResponse () {try {jsonFullPath= getClass (). GetResource (JSON_ROOT_PATH). ToURI (). GetPath ();} catch (URISyntaxException e) {e.printStackTrace ();} String json = getResponseString ("weather.json"); Gson gson = newGson (); netData= gson.fromJson (json,WeatherData.class) Model.setApiService (api); try {Field field = WeatherModel.class.getDeclaredField ("convert"); field.setAccessible (true); field.set (model,convertData);} catch (Exception e) {/ / reflect error} queryMap=newHashMap () QueryMap.put ("city", "Shenyang");} privateStringgetResponseString (String fileName) {returnFileUtil.readFile (jsonFullPath+ fileName, "UTF-8"). ToString ();} private voidsetFinalStatic (Field field,Object newValue) throwsException {field.setAccessible (true); Field modifiersField = Field.class.getDeclaredField ("modifiers"); modifiersField.setAccessible (true) ModifiersField.setint (field,field.getModifiers () & ~ Modifier.FINAL);}}

First, initialize the objects that need mock through the @ Mock annotation, and then we need to test the case analysis of the test class. The WeatherModelmode class is a network request data model, so the core of this model class is the request function. First of all, the request function is analyzed. The test points that must be covered are as follows: request parameter check, request successful and return code correctly handle logic check, request successful but check code error handle logic check and request failure handle logic check. At the same time, there is an observer unbinding function in the Model class, so the test case needs to include the unbinding function to handle the logic test. Through initResponse, we can simulate the return value of the interface. Here, the interface is returned into a Json data file by reading the Json file, and the server interface data simulation can be easily realized by combining with the Swagger document of the server.

@ Test@SuppressWarnings ("unchecked") public voidtestParams () {model.request (listener, "Shenyang"); try {Field fieldParam = WeatherModel.class.getDeclaredField ("queryMap"); Field fieldKey = WeatherModel.class.getDeclaredField ("CITY"); fieldParam.setAccessible (true); setFinalStatic (fieldKey, true); Map queryMaps = (Map) fieldParam.get (model) String key = (String) fieldKey.get (model); assertEquals ("verify queryMap's Key", key, "city"); String city = queryMaps.get ("city"); assertEquals ("verify queryMap's value", city, "Shenyang");} catch (Exception e) {/ / reflect error}}

The Api,*** step with parameters is to verify that the parameters are passed. You may feel overqualified, but many bloody tragedies tell us that smaller things are more likely to cause problems, and unit testing is to help us solve small problems in the coding period without exposing them to the public. To verify the correctness of the parameters, we first need to verify that the put to the queryMap is correct. For queryMap, we need to verify the correctness of the queryMap V key value pair, or the same prevention, because queryMap is a private variable, under normal circumstances we can not get its value, and for this variable to add a useless get/set method is too deliberate, our goal is to make the code more robust, less bug, not for testing. How can the test be carried out without getting the queryMap parameters? Does unit testing have to go from getting started to giving up? In fact, a lot of things are like this, when you feel that there is no solution to a problem, it must be that you are not thoughtful enough. The value of the queryMap object can be obtained through Java reflection. I'm not going to explain the principle of reflection here. In the testParams method, we first get the queryMap object through getDeclaredField, and then we need to get the key of put. The acquisition of key makes us into the second problem, you may say, this is not difficult, continue to reflect ah, but this key is a private static variable, through normal reflection is not able to get key, at most will get an exception. Again, don't give up looking for a solution. In the end, we found that as long as we set the virtual machine not to detect private properties, we can complete the acquisition of private static variables. Do not think that it is only a small parameter, it is not worth the effort. According to incomplete statistics, countless bug are generated every day because the interface key value is overwritten or one letter is miswritten.

@ Test@SuppressWarnings ("unchecked") public voidtestRequestSuccess () {initResponse (); Mockito.when (api.getWeather (queryMap)) .thenReturn (Observable.just (netData)); ArgumentCaptor captor = ArgumentCaptor.forClass (WeatherData.class); model.request (listener, "Shenyang"); Mockito.verify (api) .getWeather (queryMap); Mockito.verify (listener). ShowLoading (); Mockito.verify (listener). HideLoading () Mockito.verify (convertData) .convertData (captor.capture ()); WeatherData result = captor.getValue (); intstatus = result.getStatus (); assertEquals ("verify code", status,1000);}

Under the premise of guaranteed parameter transfer, we need to test the interface return status, first of all, the interface return in the successful state. The function of Mockito.when is to set the expected return result. For example, what case testRequestSuccess () is going to test is that the request is successful and the return code is correct, so our expectation of response is to let it execute the onNext method and return the correct interface data that we initialized. Mockito.when enables the test code to execute exactly as we expected. However, this declaration must be executed before the method is executed, that is, Mockito.when must be executed before model.request (listener, "Shenyang"); before it takes effect. Junit provides a rich assert assertion mechanism, and we can test in a variety of situations with assert. However, for void methods that do not have a clear return value, assert seems powerless because it cannot find a standard to assert. At this time, you need to use the verify method of mockito, which is used to verify whether a method of the mock object has been correctly executed Mockito.verify (listener). ShowLoading (); that is to verify whether the loading progress bar can be displayed properly. ArgumentCaptor is a parameter capture, which can capture the data returned by onNext. Through assert assertion, we can verify whether the data is correct in case of success. When the data is successful, we have a process of converting network data to view data, this conversion method is performed in the convert class, because we do a unit test rather than an integration test, so based on the WeatherModel test class, we only need to verify that the function convertData () is called correctly, and the content of the data conversion is tracked by the unit test of the Convert class.

Testpublic voidtestStatusError () {initResponse (); netData.setStatus (1001); Mockito.when (api.getWeather (queryMap)) .thenReturn (Observable.just (netData)); ArgumentCaptor captor = ArgumentCaptor.forClass (WeatherData.class); model.request (listener, "Shenyang"); Mockito.verify (api) .getWeather (queryMap); Mockito.verify (listener). ShowLoading () Mockito.verify (listener) .fail (null,ServerCode.get (netData.getStatus ()) .getMessage ());}

In the actual development process, the server usually makes different service response codes for different states of the same interface, although the network request is also successful when the abnormal response code is returned, but it is another situation different from the normal server response. Therefore, it is necessary to test a conditional branch of the abnormal service response code. The test method of testStatusError () is similar to that of testRequestSuccess (), except that this time our status simulation value has been changed from a successful status to an exception status, and at the same time, the function execution of verification has become a failed method of listener.

Testpublic voidtestRequestFail () {initResponse (); Exception exception = newException ("exception"); Mockito.when (api.getWeather (queryMap)) .thenReturn (Observable.error (exception)); model.request (listener, "Shenyang"); Mockito.verify (listener) .fail (null, "exception");}

Request is an interface, we can not guarantee that every request our server will be able to give an accurate response, at the same time, we can not guarantee that the user is in a smooth network state when the request is made. So when we design Model classes, we also have to take anomalies into account and handle interface exceptions, and sometimes we need to create exceptions ourselves to verify the robustness of our code. Similarly, our test class also needs a special method to ensure abnormal testing. The difference between the test method of testRequestFail () and the successful method is that what we need to mock first is not the interface data, but an exception, Exception exception = new Exception ("exception"); note that the parameter in this Exception is the exception information, because the exception information is displayed in our fail method, so this parameter must be added, otherwise e.getLocalizedMessage () will throw NPE. In addition, the expectation of Mockito.when has changed at this time, and this time we expect the function to execute the onError method.

@ Testpublic voidtestCancelRequest () {Subscription subscription = mock (Subscription.class); model.setSubscription (subscription); model.cancelRequest (); verify (subscription). Unsubscribe ();}

A case in the Model class is testCancelRequest (). Its function is to unbind the request at an appropriate time. Our network request is asynchronous, that is, when we call the requested activity or fragment destroy, there is a risk of memory leakage if we do not unbind it. Of course, the maintainers of Rxjava must have thought of what we can think of. Subscription is to make it easy for us to unbind Rx at the end of our life cycle. The verification method is simple, and it is still through the verify method to verify that the unbinding method is executed correctly.

Dependencies {classpath'com.vanniktech:gradle-android-junit-jacoco-plugin:0.6.0'}

At this point, we have completed the full coverage test of model. Click the run button in front of the test class, and you can see all the test classes running. Green represents success, and red represents a problem. You can correct the problem points caused by test failure through the Log log below. With the help of Jacoco statistical tools, you can see the unit test coverage. The reason for choosing to use Jacoco instead of IDE's native Coverage is that there is a vulnerability in Coverage in the case of test-conditional branches, so that tests that do not reach full coverage show that they are fully covered. Jacoco's AndroidStudio integration network resources are not many, and the integration methods are either potentially flawed or too cumbersome. After two days of continuous search, we finally found the simplest integration method in history. Just add a Jacoco plug-in to the gradle file of the main project, gradle will generate a Jacoco Task, and double-click to run it to generate a Html coverage report. Run our model test class, and you can see from the html generated by jacoco that our model has reached 100% full coverage. In that case, can we assume that the M layer of MVP is already ok? Wait a minute, we seem to have missed something. Yes, the data conversion class in the case of onNext has not been tested yet, so let's test the convert class.

First, let's look at the convert class code:

/ * Author: YangHaoyi on 2017-6-28. * Email: yanghaoyi@neusoft.com * Description: network data and View data Converter * Change: YangHaoYi on 2017-6-28. * Version: v 1.0 * / open classWeatherDataConvert {open funconvertData (netData: WeatherData): WeatherViewData {valviewData= WeatherViewData () viewData.temperature= netData.data?.temperature?:0.0viewData.weatherType= netData.data?.weatherType?:1viewData.ultraviolet= netData.data?.ultraviolet?:0viewData.rainfall= netData.data?.rainfall?: "0" viewData.hourTemperature= netData.data?.hourTemperature?: "10" viewData.windPower= netData.data?.windPower?: "2" returnviewData}}

From the code, we can see that our convert class looks a little strange, every mistake, because it is not java code, it is kotlin. Why should a good java project be mixed with kotlin, just to show off its skills? Of course not. The function of the data conversion class is to empty the network data and package it into view data. We all know that null detection in java requires layers of nesting. For example, we need to judge the EnglishScore field in the Score class of the Student class, which is written as follows:

If (Student! = null&&Student.getScore ()! = null&&Student.getScore () .getEnglishScore ()! = null) {}

This is a multi-layer judgment, but for kotlin we only need to write Student?.score?.englishScore, there is no significant reduction in the amount of code. For the characteristics of kotlin, interested students can move to the official website to learn more.

Let's return to the unit test. Convert class is a data null class, and its function is to assemble the data and assign default initial values, because the data on the server side is not controllable, and as a mobile phone side, we cannot completely pin the user experience on the back-end brothers, because letting go of any null data is a Crash for App. So our test point is whether this class can give a default value when the data is empty and take the network data value when the data is not empty. Here, we select a representative testTemperature as an example. First, set the value of the simulation WeatherData to 10D. Because the network data is valuable, it will take the value of the network data, that is, 10D, and the assertion comparison verification can be carried out through assertEquals. However, it should be noted that the assertion assertEquals (message,double1,double2) is not available. If you run it directly, the test will fail. Double alignment needs to add an error value, here is an error value of 0.1D, run again, the test bar turns green. At the same time, we need to test whether viewData is given the default value of 0 when WeatherData is empty. And so on, we need to validate each piece of data and package it into view data.

/ * Author: YangHaoyi on 2017-7-7. * Email: yanghaoyi@neusoft.com * Description: * Change: YangHaoYi on 2017-7-7. * Version: v 1.0 * / public classWeatherDataConvertTest {privateWeatherDataConvertconvert; private static doubleDETAL=0.1D; @ Beforepublic voidsetUp () {convert=newWeatherDataConvert ();} @ Testpublic voidtestTemperature () {WeatherData netData = newWeatherData (); WeatherData.DataBean dataBean = newWeatherData.DataBean () DataBean.setTemperature (10D); netData.setData (dataBean); WeatherViewData viewData = convert.convertData (netData); / / assert that double cannot use assertEquals (message,double1,double2) / / need to use the following method instead, where DETAL is the error value assertEquals (viewData.getTemperature (), 10D assertEquals);} @ Testpublic voidtestTemperatureNull () {WeatherData netData = newWeatherData (); WeatherData.DataBean dataBean = newWeatherData.DataBean () NetData.setData (dataBean); WeatherViewData viewData = convert.convertData (netData); / / assert that double cannot use assertEquals (message,double1,double2) / / need to use the following method instead, where DETAL is the error value assertEquals (viewData.getTemperature (), 0Dje DETAL);}}

The smooth execution of the Convert class marks the successful end of the testing of the Model layer. Let's take a look at the testing of the second sequential View layer under the MVP architecture. If we run the UI test directly without the help of the UI testing framework, we will not be able to get the expected verification, because we will only get a runtime exception. But we downloaded the corresponding version of Android SDK before building the project, so why did we still throw an exception? Why not on the real machine or simulator? Is it true that IDE only provides us with the development and compilation environment for the project, but not the running environment for the project? To quote the classic RTFSC of Linus Torvalds, let's verify our conjecture a little bit through the source code. First, we find the android.jar file corresponding to SDK, and then randomly find a project add as library. Take our most commonly used Activity as an example, the source code is as follows:

Public WindowManager getWindowManager () {throw newRuntimeException ("Stub!");} public Window getWindow () {throw newRuntimeException ("Stub!");} public LoaderManager getLoaderManager () {throw newRuntimeException ("Stub!");} public View getCurrentFocus () {throw newRuntimeException ("Stub!");} protected void onCreate (BundlesavedInstanceState) {throw newRuntimeException ("Stub!") } public void onCreate (BundlesavedInstanceState, PersistableBundle persistentState) {throw newRuntimeException ("Stub!");}

We can clean up and see that all methods throw RuntimeException ("Stub!"), which is why our test case cannot be carried out. In order to deal with the current situation that it is difficult to promote UI unit testing, Google has launched a set of UI unit testing framework called Espresso. Because it is the official framework, it is relatively perfect in the operation of the project and the follow-up of related materials. However, the shortcomings of Espresso are also obvious. Espresso can only run with the help of an Android simulator or a real machine environment, and it is precisely because it needs to run on Android devices that Espresso runs very slowly, making it even more difficult to build automatically when combined with Jenkins. This makes me wonder, if UI unit testing needs such a lot of effort, is it necessary to test it? But the iterative bug statistics soon dissuaded me from giving up the idea that UI would only do logic tests. In the iterative process, the ratio of UI to logical bug of our handset can basically reach 5: 1, that is, most of the problems occur in the view layer. The purpose of unit testing is to reduce the generation of bug. At present, UI is our pain point, and UI unit testing is imperative. After a constant search for resources, I finally came to Robolectric, a UI testing framework that can be tested without Android devices. Its design idea is to implement a set of JVM that can run Android code, so as to test without the Android environment. Because robolectric needs to download some necessary dependent packages from oss.sonatype.org, but oss.sonatype.org is a foreign website, the download speed is relatively slow. Here, you need to modify the build.gradle file of the entire project, and change mavenCentral () to the agent of Ali Cloud {"http://maven.aliyun.com/nexus/content/groups/public/"}".

The dependencies of Robolectric are:

TestCompile'org.robolectric:robolectric:3.3.2'

To run Robolectric, you need to configure the test class first, as follows:

@ RunWith (MyRobolectricTestRunner.class) @ Config (constants= BuildConfig.class,sdk=24)

MyRobolectricTestRunner is a custom configuration file pointing to Aliyun, BuildConfig is the BuildConfig file of the current model, and sdk is the version of sdk used. The sdk version is specified because Robolectric needs to download the image resources of the corresponding sdk, and the specified version will use the sdk resources that have been downloaded locally. * * when you run the test, you will automatically download the relevant files to Aliyun, and then generate a .m2 folder under the C disk of the system. If the download is still slow, you can directly copy the .m2 folder to the relative directory of your computer and use it directly. Robolectric can test almost any Android method, and it's very easy to use. For example:

@ Beforepublic voidsetUp () {activity= Robolectric.setupActivity (WeatherActivity.class);}

The realization is to create an Activity, one line of code can simulate the creation and operation of activity. One line of code solves the worry that has been bothering us about the unavailability of the android environment. With the Activity object, I feel like I can solve all the problems in an instant. For example, the jump of the test page:

@ Testpublic voidtestToHelpCenter () {view.toHelpCenter (); / / set expectation IntentIntent expectedIntent = newIntent (activity,WeatherHelpCenterActivity.class); / / get the actual IntentIntent actualIntent = ShadowApplication.getInstance (). GetNextStartedActivity (); / / verify Assert.assertEquals through Assert (expectedIntent.getComponent (), actualIntent.getComponent ());}

Set up the current page and the jump page, Robolectric can help us simulate the Intent we expect, at the same time, we can get the actual Intent value after the simulation run through ShadowApplicaiton, combined with Junit to complete the verification of Intent, and then verify the page jump logic.

TextView is one of the most commonly used and error-prone UI components in our development process, especially when the designer of the team is very imaginative and slightly different in the copywriting design of different places, it is very easy for us to type more or less, or make a mistake or close to a word. In order to ensure the quality of our products, we have to compare UI manuscripts over and over again, pinching every penny and observing them word for word. The so-called program is life, do we not have this kind of checking text trouble in our life? How do we solve it in our lives? I remember that many years ago, I occasionally saw the news that someone went to ATM to transfer money wrong. this year, however, there is very little such news, because the bank has checked the bank card number twice. The test of TextView also uses the method of secondary verification. * the text uses the business code for the second time, and the second code uses the test code for verification. If the two times are inconsistent, it proves that there is a problem with the text. In this way, the uncertainty of naked eye comparison can be effectively avoided and the program is allowed to verify the program.

@ Testpublic voidtestShowTemperature () {/ / simulated view data WeatherViewData viewData = newWeatherViewData (); viewData.setTemperature (23.1D); view.updateCache (viewData); / / execute the function to be tested view.showTemperature (); / / get the view entity TextView tvTemperature = (TextView) activity.findViewById (R.id.tvTemperature) through Id; String text = tvTemperature.getText (). ToString () / / the verification text displays assertEquals ("verification temperature", text, "23.1");}

First, through view.showTemperature (); call the execution function, find the corresponding TextView component through Id, get the display text of TextView through getText, and then verify the string through Junit's aseertEquals. If the comparison fails, you can accurately see the difference through the Log prompt click to see difference below.

Robolectric is also very easy to test for prompting Tost, as long as:

@ Testpublic voidtestShowDataError () {view.showDataError (); assertEquals ("data conversion exception", ShadowToast.getTextOfLatestToast ());}

Test the colors in Resource:

@ Testpublic voidtestInitTitle () {TextView tvTitle = (TextView) activity.findViewById (R.id.tvTitle); view.initTitle (); String title = tvTitle.getText (). ToString (); assertEquals ("verify title initialization", title, "help Center"); Application application = RuntimeEnvironment.application; ColorStateList color = ColorStateList.valueOf (application.getResources (). GetColor (R.color.colorWhite)) AssertEquals ("verify color", color,tvTitle.getTextColors ());}

Test Dialog:

@ Testpublic voidtestShowTelDialog () {view.showTelDialog (); / / because the prompt box dialog is a private variable in view and does not need to expose the method, it seems too far-fetched to write a get set method for testing / / so use the Java reflection method to get the dialog object try {/ get all the properties declared in the class through the bytecode of the class, whether private or public Field field = WeatherHelpCenterImpl.class.getDeclaredField ("telDialog") / / set access permissions (which can be said to be familiar with those who have android development experience) field.setAccessible (true); / / get the private variable value Object dialog = field.get (view); TConfirmDialog telDialog = (TConfirmDialog) dialog; / / get the Dialog object, and then get the TextView object Field fieldDialog = TConfirmDialog.class.getDeclaredField ("tvTitle") in Dialog through reflection; / / set access rights fieldDialog.setAccessible (true) / / get the TextView object in telDialog Object title = fieldDialog.get (telDialog); TextView tvTitle = (TextView) title; / / verify the title assertEquals through the assert method ("verify title", tvTitle.getText (). ToString (), "customer service phone"); / / after obtaining the Dialog object, get the TextView object fieldDialog = TConfirmDialog.class.getDeclaredField ("tvConfirm") in Dialog through reflection; / / get the TextView object Object confirm = fieldDialog.get (telDialog) in telDialog TextView tvConfirm = (TextView) confirm; / / verify the title assertEquals through the assert method ("verify OK button", tvConfirm.getText (). ToString (), "make a call"); / / after getting the Dialog object, get the TextView object fieldDialog = TConfirmDialog.class.getDeclaredField ("tvCancel") in Dialog through reflection; / / get the TextView object Object cancel = fieldDialog.get (telDialog) in telDialog; TextView tvCancel = (TextView) cancel / / verify the title assertEquals through the assert method ("verify cancel button", tvCancel.getText () .toString (), "cancel");} catch (Exception e) {/ / error}}

The test points of Dialog need to include the display and hiding of Dialog, the prompt text of Dialog and the text display of buttons. Because many of them are private variables, some Java reflections are used to help get the object.

So far, we have completed the testing of the Model layer and the View layer. Only the P layer of the MVP brothers has not been tested yet. Let's take a look at how the P layer should be tested. As the link between M layer and V layer, P layer plays a role in isolating the direct interaction between view and data. Because layer P holds only the interface of V, layer P can also be extracted into a simple pure Java test. Let's first take a look at the test code for layer P:

/ * Created by YangHaoyi on 2017-7-8. * Email: yanghaoyi@neusoft.com * Description: * Version: * / public classWeatherPresenterTest {privateWeatherPresenterpresenter; privateIWeatherViewview; privateWeatherControlcontrol; privateWeatherModelweatherModel; privateWeatherRequestListenerlistener; @ Beforepublic voidsetUp () {view=mock (IWeatherView.class); control=mock (WeatherControl.class); weatherModel=mock (WeatherModel.class); listener=mock (WeatherRequestListener.class); presenter=newWeatherPresenter (view) Presenter.updateWeatherModel (weatherModel); presenter.updateControl (control); presenter.updateListener (listener);} @ Testpublic voidtestRequest () {presenter.request (); verify (weatherModel) .request (listener,view.getLocationCity ());} @ Testpublic voidtestCancelRequest () {presenter.cancelRequest (); verify (weatherModel). CancelRequest () } @ Testpublic voidtestShowHourTemperature () {presenter.showHourTemperature (); verify (control) .pragonWasPackers (WeatherControl.TEMPERATURE);} @ Testpublic voidtestShowPrecipitation () {presenter.showPrecipitation (); verify (control) .pragonWasPackers (WeatherControl.PRECIPITATION);} @ Testpublic voidtestShowWindPower () {presenter.showWindPower (); verify (control) .pragonWasPackers (WeatherControl.WINDPOWER) @ Testpublic voidtestToHelpCenter () {presenter.toHelpCenter (); verify (view) .toHelpCenter ();}}

Because this is just an example Demo, without too much business logic, combined with a few simple design patterns, the Presenter code becomes the vast majority of sequential execution, which can be verified by Mockito's verify. What needs to be explained here is that the combination of design patterns is because the principle of unit testing is that each conditional branch needs to have a test Case as a guarantee, for multi-branches or even multiple nested branches will be more tedious, need to write a lot of repetitive code, but also increase the probability of missing tests, appropriate addition of design patterns can well make up for this, the nested conditional judgment bottom test will be deleted. Greatly reduce or even delete conditional judgment. After improving the code after the unit test, the test is only some simple if/else single branch judgment. The verification method is more or less the same as the testing method of the Model layer, and we can easily realize the testing of the Presenter layer with the help of Junit and Mockito.

These are all the contents of the article "what are the methods of android unit testing?" Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report