使用ActivityInstrumentationTestCase2测试预期的异常

时间:2015-05-27 12:44:16

标签: android eclipse unit-testing junit

我想单元测试这个简单的活动(请关注 onClick()函数):

if(navigator.onLine) {
  alert("online");
} else {
  alert("offline");
  window.open("404.html");
}

立面看起来像这样:

Facade

这是简单的JUnit测试用例(请关注 testAddDecimalValues_NumberFormatException()方法):

public class MainActivity extends Activity implements OnClickListener {

    private EditText edtValue1;
    private EditText edtValue2;
    private TextView txtResult;
    private Button btnAdd;
    private Button btnMuliply;

    private ICalculator calculator;

    final String LOG_TAG = "MainScreen";

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

        edtValue1 = (EditText) findViewById(R.id.value1);
        edtValue2 = (EditText) findViewById(R.id.value2);
        txtResult = (TextView) findViewById(R.id.result);
        btnAdd = (Button) findViewById(R.id.addValues);
        btnMuliply = (Button) findViewById(R.id.multiplyValues);

        btnAdd.setOnClickListener(this);
        btnMuliply.setOnClickListener(this);

        calculator = new Calculator();
    }

    @Override
    public void onClick(View v) {

        int val1 = 0;
        int val2 = 0;

        try {
            val1 = Integer.parseInt(edtValue1.getText().toString());
            val2 = Integer.parseInt(edtValue2.getText().toString());
        } 
        catch (NumberFormatException exc) {
            Log.e(LOG_TAG, exc.getMessage(), exc);
            throw exc;
        }

        switch (v.getId()) {

        case R.id.addValues:
            txtResult.setText(calculator.addNumbers(val1, val2).toString());
            break;

        case R.id.multiplyValues:
            txtResult.setText(calculator.multiplyNumbers(val1, val2).toString());
            break;
        }

    }
}

当我启动Unit Test testAddValues()完美地工作但 testAddDecimalValues_NumberFormatException()方法没有考虑public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> { MainActivity mainActivity; private TextView txtResult; public MainActivityTest() { super(MainActivity.class); } @Before public void setUp() throws Exception { mainActivity = getActivity(); txtResult = (TextView) mainActivity.findViewById(R.id.result); } private final static String NUMBER_24 = "2 4 ENTER "; private final static String NUMBER_74 = "7 4 ENTER "; private final static String ADD_RESULT = "98"; @After protected void tearDown() throws Exception { } @Test public void testAddValues() { sendKeys(NUMBER_24 + NUMBER_74 + "ENTER"); // get result String mathResult = txtResult.getText().toString(); assertTrue("Add result should be 98", mathResult.equals(ADD_RESULT)); } private final static String NUMBER_5_DOT_5 = "5 PERIOD 5 ENTER "; @Test(expected = NumberFormatException.class) public void testAddDecimalValues_NumberFormatException() { sendKeys(NUMBER_5_DOT_5 + NUMBER_74 + "ENTER"); } } testAddDecimalValues_NumberFormatException( )测试失败......

这是Logcat:

expected = IllegalArgumentException.class

问题是:您知道如何使用 ActivityInstrumentationTestCase2 函数来测试预期的异常吗?

非常感谢你。

PS:我尝试了来自http://www.javacodegeeks.com/2013/02/testing-expected-exceptions-with-junit-rules.html的不同方法,但我得到了相同的结果

2 个答案:

答案 0 :(得分:0)

ActivityInstrumentationTestCase2扩展junit.framework.TestCase,因此您无法使用org.junit树中的注释或类(如@TestExpectedException)与使用{{ {1}}

相反,这样做:

ActivityInstrumentationTestCase2

编辑:第二个问题是您的非测试代码。当您捕获异常时,您只有三个选项:

  1. 抓住异常,记录异常,然后继续前进而不抛出
  2. 捕获异常,用另一个异常包装异常,然后抛出新异常(不记录日志)。
  3. 再次重试操作1次,如果仍然失败,请执行选项1或2(仅限专家;此选项可能对远程呼叫有意义,您需要知道投掷的费用循环异常)
  4. 注意选项2,异常将由调用代码处理或由调用代码记录,因此如果您计划抛出异常,则无需记录异常。

    所以替换这个:

    public void testAddDecimalValues_NumberFormatException() {
      try {
        sendKeys(NUMBER_5_DOT_5 + NUMBER_74 + "ENTER");
        fail("NumberFormatException not thrown");
      } catch (NumberFormatException expected) {
      }
    }
    

    有了这个:

    try {
      val1 = Integer.parseInt(edtValue1.getText().toString());
      val2 = Integer.parseInt(edtValue2.getText().toString());
    } catch (NumberFormatException exc) {
      Log.e(LOG_TAG, exc.getMessage(), exc);
      throw exc;
    }
    

答案 1 :(得分:0)

最后,我认为 ActivityInstrumentationTestCase2 无法测试预期的异常,因为 ActivityInstrumentationTestCase2 用于自动化手动测试,并且手动测试不能用于测试遇到例外...... 这就是为什么,为了测试错误情况,我们只能在商务舱上进行单元测试。

MainActivity 类中,我必须处理异常。如果你愿意,我可以发布我的代码解决方案。

谢谢