Android中如何测试assert抛出异常

发布于 2024-12-06 15:09:33 字数 357 浏览 1 评论 0原文

在 Android 中是否有更优雅的方法来执行断言抛出异常?

public void testGetNonExistingKey() {   
        try {
            alarm.getValue("NotExistingValue");
            fail( );
        } catch (ElementNotFoundException e) {

        }
}

这样的事不行吗?!

    @Test(expected=ElementNotFoundException .class)

谢谢,马克

is there a more elegant way to do an assert throws exception in Android then this?

public void testGetNonExistingKey() {   
        try {
            alarm.getValue("NotExistingValue");
            fail( );
        } catch (ElementNotFoundException e) {

        }
}

Something like this does not work?!

    @Test(expected=ElementNotFoundException .class)

Thanks, Mark

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

心凉怎暖 2024-12-13 15:09:33

您使用的是 junit4 测试运行程序吗?如果您正在运行 junit3 测试运行程序,则 @Test 注释将不起作用。检查您正在使用的版本。

其次,检查代码中异常的推荐方法是使用规则(在 junit 4.7 中引入)。

@Rule
public ExpectedException exception = ExpectedException.none();

@Test
public void throwsIllegalArgumentExceptionIfIconIsNull() {
    // do something

    exception.expect(IllegalArgumentException.class);
    exception.expectMessage("Icon is null, not a file, or doesn't exist.");
    new DigitalAssetManager(null, null);
}

您可以继续使用@Test(expected=IOException.class),但上面的好处是,如果在调用exception.expect之前抛出异常,那么测试将失败。

Are you using a junit4 test runner? The @Test annotation won't work if you're running a junit3 test runner. Check the version that you're using.

Secondly, the recommended way to check for exceptions in your code is to use a Rule (introduced in junit 4.7).

@Rule
public ExpectedException exception = ExpectedException.none();

@Test
public void throwsIllegalArgumentExceptionIfIconIsNull() {
    // do something

    exception.expect(IllegalArgumentException.class);
    exception.expectMessage("Icon is null, not a file, or doesn't exist.");
    new DigitalAssetManager(null, null);
}

You can continue to use the @Test(expected=IOException.class), but the above has the advantage that if an exception is thrown before the exception.expect is called, then the test will fail.

落叶缤纷 2024-12-13 15:09:33

我做了一些与hopia的答案非常相似的事情,但做了一些改进。我让它返回异常对象,以便您可以检查其消息或任何其他属性,并且我声明了一个 Testable 接口来替换 Runnable 因为 Runnable > 不允许您的测试代码抛出已检查的异常。

public interface Testable {
    public void run() throws Exception;
}

public <T extends Exception> T assertThrows(
        final Class<T> expected, 
        final Testable codeUnderTest) throws Exception {
    T result = null;
    try {
        codeUnderTest.run();
        fail("Expecting exception but none was thrown.");
    } catch(final Exception actual) {
        if (expected.isInstance(actual)) {
            result = expected.cast(actual);
        }
        else {
            throw actual;
        }
    }
    return result;
}

这是调用它的示例。

InvalidWordException ex = assertThrows(
    InvalidWordException.class,
    new Testable() {
        @Override
        public void run() throws Exception {
            model.makeWord("FORG", player2);
        }
    });

assertEquals(
        "message", 
        "FORG is not in the dictionary.", 
        ex.getMessage());

I did something very similar to hopia's answer with a couple of improvements. I made it return the exception object so that you can check its message or any other properties, and I declared a Testable interface to replace Runnable because Runnable doesn't let your code under test throw checked exceptions.

public interface Testable {
    public void run() throws Exception;
}

public <T extends Exception> T assertThrows(
        final Class<T> expected, 
        final Testable codeUnderTest) throws Exception {
    T result = null;
    try {
        codeUnderTest.run();
        fail("Expecting exception but none was thrown.");
    } catch(final Exception actual) {
        if (expected.isInstance(actual)) {
            result = expected.cast(actual);
        }
        else {
            throw actual;
        }
    }
    return result;
}

Here's an example of calling it.

InvalidWordException ex = assertThrows(
    InvalidWordException.class,
    new Testable() {
        @Override
        public void run() throws Exception {
            model.makeWord("FORG", player2);
        }
    });

assertEquals(
        "message", 
        "FORG is not in the dictionary.", 
        ex.getMessage());
绳情 2024-12-13 15:09:33

如果您使用 Kotlin,则可以利用 具体化类型 以避免将 Exception 子类作为参数传递:

inline fun <reified T : Exception> assertThrows(runnable: () -> Any?) {
    try {
        runnable.invoke()
    } catch (e: Throwable) {
        if (e is T) {
            return
        }
        Assert.fail("expected ${T::class.qualifiedName} but caught " +
            "${e::class.qualifiedName} instead")
    }
    Assert.fail("expected ${T::class.qualifiedName}")
}

@Test
fun exampleTest() {
    val a = arrayOf(1, 2, 3)
    assertThrows<IndexOutOfBoundsException> {
        a[5]
    }
}

If you're using Kotlin, you can take advantage of reified types to avoid passing the Exception subclass as an argument:

inline fun <reified T : Exception> assertThrows(runnable: () -> Any?) {
    try {
        runnable.invoke()
    } catch (e: Throwable) {
        if (e is T) {
            return
        }
        Assert.fail("expected ${T::class.qualifiedName} but caught " +
            "${e::class.qualifiedName} instead")
    }
    Assert.fail("expected ${T::class.qualifiedName}")
}

@Test
fun exampleTest() {
    val a = arrayOf(1, 2, 3)
    assertThrows<IndexOutOfBoundsException> {
        a[5]
    }
}
本宫微胖 2024-12-13 15:09:33

我就是这样做的。我创建了一个名为assertThrowsException 的静态方法,该方法接受预期异常类和包含被测试代码的Runnable 作为参数。

import junit.framework.Assert;

public SpecialAsserts {
    public void assertThrowsException(final Class<? extends Exception> expected, final Runnable codeUnderTest) {
        try {
            codeUnderTest.run();
            Assert.fail("Expecting exception but none was thrown.");
        } catch(final Throwable result) {
            if (!expected.isInstance(result)) {
                Assert.fail("Exception was thrown was unexpected.");
            }
        }
    }
}

这是在测试类(扩展 AndroidTestCase 或其衍生物之一)中使用特殊断言的示例代码:

public void testShouldThrowInvalidParameterException() {

    SpecialAsserts.assertThrowsException(InvalidParameterException.class, new Runnable() {
        public void run() {
            callFuncThatShouldThrow();
        }
    });

}

是的,有很多工作,但它比将 junit4 移植到 android 更好。

This is how I do it. I create a static method called assertThrowsException that takes in as arguments an expected exception class and a Runnable which contains the code under test.

import junit.framework.Assert;

public SpecialAsserts {
    public void assertThrowsException(final Class<? extends Exception> expected, final Runnable codeUnderTest) {
        try {
            codeUnderTest.run();
            Assert.fail("Expecting exception but none was thrown.");
        } catch(final Throwable result) {
            if (!expected.isInstance(result)) {
                Assert.fail("Exception was thrown was unexpected.");
            }
        }
    }
}

This is the sample code to use the special assert in your test class (that extends AndroidTestCase or one of its derivatives):

public void testShouldThrowInvalidParameterException() {

    SpecialAsserts.assertThrowsException(InvalidParameterException.class, new Runnable() {
        public void run() {
            callFuncThatShouldThrow();
        }
    });

}

Yes, there's a lot of work, but it's better than porting junit4 to android.

夜司空 2024-12-13 15:09:33

对于 junit3,以下内容可能会有所帮助。

public static void assertThrows(Class<? extends Throwable> expected,
        Runnable runnable) {
    try {
        runnable.run();
    } catch (Throwable t) {
        if (!expected.isInstance(t)) {
            Assert.fail("Unexpected Throwable thrown.");
        }
        return;
    }
    Assert.fail("Expecting thrown Throwable but none thrown.");
}

public static void assertNoThrow(Runnable runnable) {
    try {
        runnable.run();
    } catch (Throwable t) {
        Assert.fail("Throwable was unexpectedly thrown.");
    }
}

With junit3 the following might help.

public static void assertThrows(Class<? extends Throwable> expected,
        Runnable runnable) {
    try {
        runnable.run();
    } catch (Throwable t) {
        if (!expected.isInstance(t)) {
            Assert.fail("Unexpected Throwable thrown.");
        }
        return;
    }
    Assert.fail("Expecting thrown Throwable but none thrown.");
}

public static void assertNoThrow(Runnable runnable) {
    try {
        runnable.run();
    } catch (Throwable t) {
        Assert.fail("Throwable was unexpectedly thrown.");
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文