Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Robolectric Test for AlertDialog

I am new to robolectric and I am trying to make a test for a button that creates an AlertDialog. When the button is clicked, an AlertDialog is made with a positive button that I want to click using Robolectric, and test if it launches an activity. Here is the code for the button:

newUserButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AlertDialog.Builder builder = new AlertDialog.Builder(StartActivity.this);
            builder.setTitle(context.getResources().getString(R.string.start_title_message))
                    .setMessage(getResources().getString(R.string.start_dialog_message));
            builder.setPositiveButton(getString(R.string.start_confirm_message), new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    startActivityForResult(new Intent(StartActivity.this, AvatarRoomActivity.class), 0);
                }
            });
            builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.dismiss();
                }
            });
            AlertDialog dialog = builder.create();
            ColorDrawable drawable = new ColorDrawable(Color.WHITE);
            drawable.setAlpha(200);
            dialog.getWindow().setBackgroundDrawable(drawable);
            dialog.show();
        }
    });

Does anyone know how I can test clicking the positive button, then launching AvatarRoomActivity? Thanks in advance and hope to hear from someone soon.

like image 869
Erika Avatar asked Dec 05 '17 14:12

Erika


People also ask

How many buttons can be set up on an AlertDialog?

Dialog Design AlertDialog. A dialog that can show a title, up to three buttons, a list of selectable items, or a custom layout.

What is the difference between dialog and AlertDialog?

AlertDialog is a lightweight version of a Dialog. This is supposed to deal with INFORMATIVE matters only, That's the reason why complex interactions with the user are limited. Dialog on the other hand is able to do even more complex things .

How do I view AlertDialog?

Alert Dialog code has three methods:setTitle() method for displaying the Alert Dialog box Title. setMessage() method for displaying the message. setIcon() method is used to set the icon on the Alert dialog box.

What is the correct syntax for creating an object of AlertDialog builder to make an alert dialog?

AlertDialog alertDialog = alertDialogBuilder. create(); alertDialog. show(); This will create the alert dialog and will show it on the screen.


2 Answers

I came across this problem today, and exposing a private function just for testing is not advised.

Robolectric provides a ShadowAlertDialog, which can detect a shown Dialog or AlertDialog.

//get all shown dialogs    
ShadowAlertDialog.getShownDialogs()

//get single dialog  
(ShadowAlertDialog.getLatestDialog() as android.support.v7.app.AlertDialog)
    .getButton(AlertDialog.BUTTON_POSITIVE)
    .performClick()

//Continue the test
like image 79
zabson Avatar answered Oct 14 '22 00:10

zabson


Let's forget the newUserButton for a while. It is not relevant to the problem.

You will need to expose the AlertDialog object so that it is accessible in unit test code. So I assume you activity have such a method in StartActivity:

AlertDialog showDialog() {

    AlertDialog.Builder builder = new AlertDialog.Builder(StartActivity.this);
    builder.setTitle("This is title")
            .setMessage("Dialog Message");
    builder.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            startActivityForResult(new Intent(this, AvatarRoomActivity.class), 0);
        }
    });
    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            dialog.dismiss();
        }
    });
    AlertDialog dialog = builder.create();
    dialog.show();

    return dialog;

}

then the click event of newUserButton just invoke this method.

Then we have the test case like this:

@Test
public void testLaunchAvatarRoomWhenConfirm() {

    StartActivity startActivity = Robolectric.buildActivity(StartActivity.class).create().get();

    AlertDialog dialog = startActivity.showDialog();

    // Key part 1 : simulate button click in unit test
    Button confirm = dialog.getButton(Dialog.BUTTON_POSITIVE);
    confirm.performClick();

    // Key part 2 : Check that startActivityForResult is invoke
    ShadowActivity shadowActivity = shadowOf(startActivity);
    ShadowActivity.IntentForResult intentForResult = shadowActivity.getNextStartedActivityForResult();

    // assert that the proper request to start activity is sent
    ComponentName nextActivity = intentForResult.intent.getComponent();
    assertEquals(".AvatarRoomActivity", nextActivity.getShortClassName());

}

This test method verify that when the dialog's positive button is clicked, startActivityForResult is invoked with proper activity class name.

So the remaining problem is how do we ensure the activity is really resolved and launched. Normally I would stop at this point for testing of alert dialog actions. Whether the intent can be resolved and start activity property is out of the scope of this particular test case.

like image 24
Herman Cheung Avatar answered Oct 14 '22 00:10

Herman Cheung