当互联网连接不可用时,测试警报的显示robolectric android

时间:2014-09-11 05:34:26

标签: android eclipse junit4 robolectric

我正在使用Roboelectric来测试一个简单的android应用。它有一个活动,有一个按钮,点击按钮,它会显示一条警报消息,无论我是否连接到互联网。我正在使用ConnectivityManager并检查WiFiMobile网络的可用性。

这是按钮的onClick方法。

 netButton.setOnClickListener(new OnClickListener(){
 @Override
 public void onClick(View v) {
 if(isConnectedToInternet()){
 new AlertDialog.Builder(MainActivity.this).setMessage("You are connected to internet").setNeutralButton("OK", new DialogInterface.OnClickListener() {
     public void onClick(DialogInterface dialog, int which) {
         dialog.cancel();
     }
 }).show();
 }
 else{
 new AlertDialog.Builder(MainActivity.this).setMessage("You are not connected to internet").setNeutralButton("OK", new DialogInterface.OnClickListener() {
 public void onClick(DialogInterface dialog, int which) {
     dialog.cancel();
 }
}).show();
}
}
});

isConnectedToInternet方法为 -

public boolean isConnectedToInternet(){
connManager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo wifiNetwork =connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
NetworkInfo mobileNetwork = connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (wifiNetwork!=null && wifiNetwork.isConnected()){
return true;
else if (mobileNetwork!=null && mobileNetwork.isConnected()){
return true;
return false;
}

该应用运行良好。此外,当我使用Roboelectric运行它时,并手动设置连接类型为Mobile or WiFi以测试是否显示警报,测试和断言运行正常。但是如果我将类型设置为任何other类型(假设WIMAX或与任何类型0x0000000A无关的常量),它总是映射到类型Mobile(常量0x00000000)

以下是我的代码,用于检查互联网的不可用性以及警报消息的显示。

'MainActivityTest.java'

    public void testAlertForNonNetwork(){
    setUpActivity();

    connManager=(ConnectivityManager)Robolectric.application.getSystemService(Context.CONNECTIVITY_SERVICE);
    ShadowConnectivityManager sConnManager=Robolectric.shadowOf_(connManager);
    sConnManager.setNetworkInfo(0x0000000A,sConnManager.getActiveNetworkInfo());
    pushSecondButton();
    AlertDialog alert=ShadowAlertDialog.getLatestAlertDialog();
    assertNotNull("the alert is null",alert!=null);
    ShadowAlertDialog sAlert=shadowOf_(alert);
    assertNotNull("the salert is null",sAlert!=null);
    assertThat(sAlert.getMessage().toString(),equalTo("You are not connected to internet"));
    }

此处setUpActivitypushSecondButton是设置活动和按下按钮的简单方法。

这个断言总是失败。有趣的是,如果我在MainActivity.java中注释检查与移动数据的连接的代码,那么我的断言就会成功运行,

有没有人知道,为什么Roboelectric将任何其他连接映射到Mobile,以防我在MainActivityTest中使用ConnectivityManager.WIMAX而不是常量0x0000000A,这种行为是可复制的。

我尝试使用System.out.println(xxxNetwork.getType())显示该值,而WiFi和移动设备以外的任何类型都会映射到Mobile, the constant 0

2 个答案:

答案 0 :(得分:1)

我无法重新提出您提到的返回类型移动设备的错误信息。当我查询ShadowConnectivityManager时,任意类型(包括TYPE_WIMAX和int 35)都返回null。这是我所期待的行为,这是令人欣慰的。

至于为什么你的测试失败,我相信这是因为默认情况下Robolectric添加了TYPE_WIFITYPE_MOBILE NetworkInfo。见the source。默认设置表示移动设备已连接且wifi已断开连接。我不确定为什么会这样。以下是相关代码:

  public ShadowConnectivityManager() {
    NetworkInfo wifi = ShadowNetworkInfo.newInstance(NetworkInfo.DetailedState.DISCONNECTED, ConnectivityManager.TYPE_WIFI, 0, true, false);
    networkTypeToNetworkInfo.put(ConnectivityManager.TYPE_WIFI, wifi);

    NetworkInfo mobile = ShadowNetworkInfo.newInstance(NetworkInfo.DetailedState.CONNECTED, ConnectivityManager.TYPE_MOBILE, ConnectivityManager.TYPE_MOBILE_MMS, true, true);
    networkTypeToNetworkInfo.put(ConnectivityManager.TYPE_MOBILE, mobile);

    this.activeNetwork = mobile;
  }

在你的测试中,我会首先设置我期望的NetworkInfo。在您的情况下,这将设置wifi和移动设备断开连接。

我还建议使用命名的int而不是原始值,例如: TYPE_WIMAX而不是0x0000000A或映射到的常量。这将使其更易于阅读和维护。

修改

评论中的空格不足。为了修复测试,我首先要确保在每次测试开始时系统处于已知状态。你试图这样做,它看起来像,但是由于robolectric在这些默认情况下失败而被挫败。因此,在您的@Before方法(或setUp()@Before模拟中,如果您正在使用JUnit 3),我会将移动值设置为已断开连接。当然,你也可以在每个测试的基础上做到这一点 - 无论什么是最有意义的。

在我的@Before方法中,我使用ShadowConnectivityManager表示移动设备已断开连接,然后我断言在单一测试中确实如此。我从未在自己的测试中使用过这个,所以你可能需要调整一下以确保newInstance()的所有参数都正确。例如,我不知道我的头顶优先 - 第一个参数或最后一个参数,所以如果你说DetailedState.CONNECTED和最后一个参数false我不会&#39 ;知道isConnected()会返回什么。

我可以保证,在我当前的设置中,此测试通过,如果我删除了对setNetworkInfo()的调用,则会失败。

您可能还希望将ConnectivityManager对象移动到类字段以保持清洁,看起来您已经在代码中完成了。当然,如果你选择这条路线,请确保在测试之间重置任何必要的状态。

  @Before
  public void before() {

    ConnectivityManager cm = (ConnectivityManager)
        Robolectric.application.getSystemService(Context.CONNECTIVITY_SERVICE);

    ShadowConnectivityManager shadowCM = Robolectric.shadowOf(cm);

    shadowCM.setNetworkInfo(
        ConnectivityManager.TYPE_MOBILE,
        ShadowNetworkInfo.newInstance(
            DetailedState.DISCONNECTED,
            ConnectivityManager.TYPE_MOBILE,
            ConnectivityManager.TYPE_MOBILE_MMS,
            true,
            false));


  }

  @Test
  public void mobileIsDisconnected() {
    ConnectivityManager cm = (ConnectivityManager)
        Robolectric.application.getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo mobileInfo =
        cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

    assertThat(mobileInfo.isConnected()).isFalse();
  }

答案 1 :(得分:0)

    if (hasConnection()) {

//write your code
}
else{
Open_dilog();
}


//Method of Open_dilog()


private void Open_dilog() {
        // TODO Auto-generated method stub

        AlertDialog.Builder builder = new AlertDialog.Builder(
                Sharing_activity.this);
        builder.setTitle("Title name");
        builder.setMessage("No Internet Connection Available.");
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
                dialog.dismiss();

            }
        });
        AlertDialog dialog_show = builder.create();
        dialog_show.show();

    }

public static boolean hasConnection(){     ConnectivityManager cm =(ConnectivityManager)this.getContext()。getSystemService(         Context.CONNECTIVITY_SERVICE);

NetworkInfo wifiNetwork = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (wifiNetwork != null && wifiNetwork.isConnected()) {
  return true;
}

NetworkInfo mobileNetwork = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (mobileNetwork != null && mobileNetwork.isConnected()) {
  return true;
}

NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null && activeNetwork.isConnected()) {
  return true;
}

return false;

}