【问题标题】:Assert exceptions in Android Espresso test在 Android Espresso 测试中断言异常
【发布时间】:2018-05-28 09:53:06
【问题描述】:

我在 Espresso 中有一个测试,需要断言某个操作会导致引发异常。

但是,Espresso 框架似乎吞下了原始异常,只显示了 PerformException

【问题讨论】:

    标签: android unit-testing android-espresso


    【解决方案1】:

    最终我找到了一种方法。 我创建了一个自定义 Hamcrest 匹配器,允许您验证嵌套异常。

    public class NestedExceptionMatcher extends TypeSafeMatcher<Throwable> {
    
        private final Class<?> mExpectedType;
        private final Matcher<String> mMessageMatcher;
    
        static NestedExceptionMatcher expectNestedThrowable(Class<?> expectedType, Matcher<String> messageMatcher) {
            return new NestedExceptionMatcher(expectedType, messageMatcher);
        }
    
        NestedExceptionMatcher(Class<?> expectedType, Matcher<String> messageMatcher) {
            mExpectedType = expectedType;
            mMessageMatcher = messageMatcher;
        }
    
        @Override
        protected boolean matchesSafely(Throwable item) {
            boolean matches = isMatch(item);
    
            Throwable currentThrowable = item.getCause();
            while (!matches && currentThrowable != null) {
                matches = isMatch(currentThrowable);
                currentThrowable = currentThrowable.getCause();
            }
    
            return matches;
        }
    
        @Override
        public void describeTo(Description description) {
            description
                    .appendText("expects type ")
                    .appendValue(mExpectedType)
                    .appendText(" with a message ")
                    .appendDescriptionOf(mMessageMatcher);
        }
    
        private boolean isMatch(Throwable t) {
            return t.getClass().isAssignableFrom(mExpectedType) && mMessageMatcher.matches(t.getMessage());
        }
    }
    

    然后你可以在你的测试中使用它:

    public class SomeActivityTest {
    
        @Rule
        public ActivityTestRule<SomeActivity> mRule = new ActivityTestRule<>(
                SomeActivity.class, false, false);
    
        @Rule
        public ExpectedException mExceptionRule = ExpectedException.none();
    
        @Test
        public void testClick_whenInvalidParamsAreSet_shouldThrowException() {
            mRule.launchActivity(getIntentWithInvalidParams());
            mExceptionRule.expect(expectNestedThrowable(
                    IllegalArgumentException.class,
                    containsString("parameter isn't defined")
            ));
    
            onView(withId(R.id.my_btn)).perform(click());
        }
    
        private Intent getIntentWithInvalidParams() {
            ...
        }
    }
    

    【讨论】:

    • 这对我有用。我现在可以捕获预期的异常了。
    • 帮了我很多忙!
    【解决方案2】:

    你可以这样做

    @Test( expected = ArrayIndexOutOfBoundsException.class) //OR any other  
    throwable
    public void myTest() {
    
    }
    

    【讨论】:

    • 这在 Espresso 测试中不起作用,因为 Espresso 将所有异常都包装在了 PerformException 中
    【解决方案3】:

    为什么不用这个:

     @Test(expected = PerformException::class)
        fun traderSummaryContainer_notScroll() {
            onView(withId(R.id.traderSummaryContainer))
                    .perform(scrollTo())
        }
    

    【讨论】:

    • 这不是我感兴趣的例外。 PerformException 是一个包含“有趣”异常的 Espresso 异常。在我发布的示例中,“有趣”的异常是“IllegalArgumentException”
    【解决方案4】:

    使用正常的 try catch 解决了我的问题,我知道异常是嵌套的。 但是我们仍然可以按原因检查它:

        var error: Throwable? = null
        try {
            onView(something).perform(click())
        } catch (e: Throwable) {
            error = e;
        }
        assert(error!!.cause is MySpecificException)
        assert(error!!.cause!!.message == "My specific error message")
    
    

    我已经尝试了上述自定义 Hamcrest 匹配器方法,但我最终得到了不稳定的测试,所以最终移到了这个。

    【讨论】:

      【解决方案5】:

      为什么不使用 Assert.assertThrows(Class expectedThrowable, ThrowingRunnable runnable) 或 Assert.assertThrows(String message, Class expectedThrowable, ThrowingRunnable runnable)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-16
        • 2021-10-21
        • 1970-01-01
        • 2019-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多