How to test your Android application with Mockito ?

Hi guys,

Today I’m going to show you how to test your  Android app.

Testing your application is crucial and is a must. Why is it important ?Guess why, because do you want to release your apps infested with bugs and receive some bad reviews from users ? Of course not ! Then you will have to follow some of the simple steps ! By the way, you will have to have  some knowledge on JUnit otherwise, you might get stuck somewhere !

[Prepare the sample android project]

First of all, before we get started download or checkout the following git

and set up the sample project in your android studio. (I don’t use eclipse for my android projects anymore!)

https://github.com/treehouse/android-testing-project.git

 

[Lets get started!]

Ok, if you open the project inside the android studio, you will notice that there are only some 2 simple files, “MainActivity & OtherActivity”.

[Set the dependencies]

First, in order to use Mockito, you will have to set the following snippet inside the gradle app file. Where ? Inside the dependencies.

testCompile "org.mockito:mockito-core:1.+"

[We need more classes! ]

We need to add more classes to do the test ? Yes, it sucks that there should be additional classes to do the test.

But wait ! Which part of the section are we going to test ?

There are 3 sections that we will be testing.

  1. Around line 50, where the text is being set. Why ? We need to check if the expected value is been set.
     textView.setText(text);

2.  Inside colorSpinner.setOnItemSelectedListener, where the switch  statement is been used. For what ? We will have to check if the correct color is been used or not.

3.  We will also have to check the  part where transitioning to other activity is been handled.

Intent intent = new Intent(MainActivity.this, OtherActivity.class);
startActivity(intent);

Sounds quite easy ! Kind of …

So we are going to be refactoring this projects code so that the testing can be done with much ease! Let’s create a interface called “MainActivityView”.

We will be adding the following code so that we can replace it with the codes mentioned above… Did I mention it ? Anyway here it is.

public interface  MainActivityView {
    void changeTextViewText(String text); // For changing the textView
    void changeBackgroundColor(int color); //For changing the color
    void launchOtherActivity(Class activity); //for launching other class
}

Next we are going to be making a class called “MainActivityPresenter”….

What is it for ? The methods in this class will be using the methods from the MainActivityView and will be used for refactoring the codes in the MainActivity and will also be used for testing.  Here are the following code.

public class MainActivityPresenter {

    MainActivityView View;

    public MainActivityPresenter (MainActivityView view) {
        this.View = view;
    }

    public void editTextUpdated(String text) {
        View.changeTextViewText(text);
    }

    public void colorSelected(int index) {
        switch (index) {
            case 0:
                View.changeBackgroundColor(Color.WHITE);
                break;
            case 1:
                View.changeBackgroundColor(Color.MAGENTA);
                break;
            case 2:
                View.changeBackgroundColor(Color.GREEN);
                break;
            case 3:
                View.changeBackgroundColor(Color.CYAN);
                break;
        }
    }

    public void changeOtherActivityButtonClicked(Class activity) {
        View.launchOtherActivity(activity);
    }
}

Now we are going to right click the MainActivityPresenter class and select Go to -> Test.  Select Create new Test..  You will see a dialog showing many stuffs, but first select the checkbox “setUp/@Before”,  and check all 3 member methods. Finally tap Ok and your set !  But maybe you don’t want to do the long typing anymore, so here is the cheat code that you can paste in the Testing class that was just made.

@RunWith(MockitoJUnitRunner.class)
public class MainActivityPresenterTest {

    MainActivityPresenter presenter;

    @Mock
    MainActivityView view;

    @Before
    public void setUp() throws Exception {
      
        presenter = new MainActivityPresenter(view);
    }

    @Test
    public void testEditTextUpdated() throws Exception {

        //Arrange
        String givenString = "test123";

        //Act
        presenter.editTextUpdated(givenString);

        //Assert
        Mockito.verify(view).changeTextViewText(givenString);

    }

    @Test
    public void testColorSelected() throws Exception {

        // Arrange
        int index  = 2;
        int givenColor = Color.GREEN;

        // Act
        presenter.colorSelected(index);

        // Assert
        Mockito.verify(view).changeBackgroundColor(givenColor);

    }

    @Test
    public void testChangeOtherActivityButtonClicked() throws Exception {

        //Arrange
        Class clazz = OtherActivity.class;

        //Act
        presenter.changeOtherActivityButtonClicked(clazz);


        //Assert
        Mockito.verify(view).launchOtherActivity(clazz);
    }
}

Actually, everything in here is quite self explanatory, so I guess there is not so much for me to explain but for a simple hint, here’s what the following code is doing. Do you remember that inside the MainActivity class where the switch statement is been used for changing the background color ?  We will be replacing that switch statement with  presenter.colorSelected(index);, so  before we use it , we need  to check if the index will return the  expected value or not .

Actually the following code is  just comparing if the index and the givenColor is returning the same result by using Mockito’s verify method.

If the result doesn’t match, the log will show up some errors that you can use it to track the problem.

    @Test
    public void testColorSelected() throws Exception {

        // Arrange
        int index  = 2;
        int givenColor = Color.GREEN;

        // Act
        presenter.colorSelected(index);

        // Assert
        Mockito.verify(view).changeBackgroundColor(givenColor);

    }

Here’s how the final result for the MainActivity will look like.

public class MainActivity extends AppCompatActivity implements MainActivityView {
    LinearLayout linearLayout;
    EditText editText;
    TextView textView;
    Spinner colorSpinner;
    Button launchActivityButton;

    MainActivityPresenter presenter;

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

        presenter = new MainActivityPresenter(this);
        // Initialize Views
        textView = (TextView) findViewById(R.id.textView);
        editText = (EditText) findViewById(R.id.editText);
        launchActivityButton = (Button) findViewById(R.id.launchActivityButton);
        linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
        colorSpinner = (Spinner) findViewById(R.id.colorSpinner);

        // Setup Spinner
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
                R.array.colors_array, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        colorSpinner.setAdapter(adapter);

        editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView tv, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    String text = tv.getText().toString();
                   // textView.setText(text);
                    presenter.editTextUpdated(text);
                }
                return false;
            }
        });

        colorSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {


            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int index, long id) {
                presenter.colorSelected(index);
                /*
                switch (index) {
                    case 0:
                        linearLayout.setBackgroundColor(Color.WHITE);
                        break;
                    case 1:
                        linearLayout.setBackgroundColor(Color.MAGENTA);
                        break;
                    case 2:
                        linearLayout.setBackgroundColor(Color.GREEN);
                        break;
                    case 3:
                        linearLayout.setBackgroundColor(Color.CYAN);
                        break;
                }
                */
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {}
        });

        launchActivityButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                presenter.changeOtherActivityButtonClicked(OtherActivity.class);
            }
        });
    }

    @Override
    public void changeTextViewText(String text) {
        textView.setText(text);
    }

    @Override
    public void changeBackgroundColor(int color) {
        linearLayout.setBackgroundColor(color);
    }

    @Override
    public void launchOtherActivity(Class activity) {
        Intent intent = new Intent(MainActivity.this, activity);
        startActivity(intent);
    }
}

That’s all! After all I’m also a novice when it comes to JUnit testing so I guess that I wasn’t able to explain well.  See you in the next tip ! And for more information on Mockito, check out there official website ! It’s well documented and really cool !

http://mockito.org/

Leave a Reply

Your email address will not be published. Required fields are marked *