Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用junit@Rule、expectCause()和hamcrest匹配器_Java_Unit Testing_Maven_Junit - Fatal编程技术网

Java 使用junit@Rule、expectCause()和hamcrest匹配器

Java 使用junit@Rule、expectCause()和hamcrest匹配器,java,unit-testing,maven,junit,Java,Unit Testing,Maven,Junit,我有一个测试: @Rule public ExpectedException thrown = ExpectedException.none(); ... @Test public void testMethod() { final String error = "error message"; Throwable expectedCause = new IllegalStateException(error); thrown.expectCause(org.hamcre

我有一个测试:

@Rule
public ExpectedException thrown = ExpectedException.none();
...
@Test
public void testMethod()
{
    final String error = "error message";
    Throwable expectedCause = new IllegalStateException(error);
    thrown.expectCause(org.hamcrest.Matchers.<Throwable>equalTo(expectedCause));
    someServiceThatTrowsException.foo();
}
@规则
抛出公共ExpectedException=ExpectedException.none();
...
@试验
公共void testMethod()
{
最终字符串error=“error message”;
Throwable expectedCause=新的非法状态异常(错误);
expectCause(org.hamcrest.Matchers.equalTo(expectedCause));
someServiceThrowsException.foo();
}
当通过mvn测试方法运行时,我得到错误:

java.lang.NoSuchMethodError: org.junit.rules.ExpectedException.expectCause(Lorg/hamcrest/Matcher;)V

测试编译得很好

请帮助我,无法理解如何测试异常的原因?

请尝试以下方法:

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

@Test public void testMethod() throws Throwable {
    final String error = "error message";
    Throwable expectedCause = new IllegalStateException(error);
    thrown.expectCause(IsEqual.equalTo(expectedCause));
    throw new RuntimeException(expectedCause);
}
考虑不通过equals检查原因,而是在必要时通过IsInstanceOf和/或comapring异常消息进行检查。通过equals比较原因,同时检查stacktrace,这可能比您想要测试/检查的要多。例如:

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

@Test public void testMethod() throws Throwable {
    final String error = "error message";
    thrown.expectCause(IsInstanceOf.<Throwable>instanceOf(IllegalStateException.class));
    thrown.expectMessage(error);
    throw new RuntimeException(new IllegalStateException(error));
}
@Rule public ExpectedException抛出=ExpectedException.none();
@Test public void testMethod()抛出可丢弃的{
最终字符串error=“error message”;
抛出.expectCause(IsInstanceOf.instanceOf(IllegalStateException.class));
抛出.expectMessage(错误);
抛出新的RuntimeException(新的IllegalStateException(错误));
}

这是JUnit版本的问题

ExpectedException.expectCause()
是自

中或更低版本中没有此类方法


您应该确保运行时JUnit版本>=4.11,与编译版本相同。

您可以使用此处所述的自定义匹配器()来测试异常的原因

定制匹配器
使用静态导入并检查类和原因异常的消息时,要稍微简单一点:

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@Test
public void testThatThrowsNiceExceptionWithCauseAndMessages(){

     expectedException.expect(RuntimeException.class );
     expectedException.expectMessage("Exception message");                                           
     expectedException.expectCause(allOf(instanceOf(IllegalStateException.class),
                                        hasProperty("message", is("Cause message"))) );

     throw new RuntimeException("Exception message", new IllegalStateException("Cause message"));
}
您甚至可以使用hasProperty匹配器来断言嵌套原因或测试“getLocalizedMessage”方法

hamcrest的any(Class)matcher运行良好:

@Rule
public ExpectedException thrown = ExpectedException.none();
...
@Test
public void testMethod()
{
    thrown.expect(RuntimeException.class);
    thrown.expectCause(org.hamcrest.Matchers.any(IllegalStateException.class));
}

通常我更喜欢以下结构:

expectedException.expectCause(isA(NullPointerException.class));

导入

<dependency>
  <groupId>it.ozimov</groupId>
  <artifactId>java7-hamcrest-matchers</artifactId>
  <version>1.3.0</version>
  <scope>test</scope>
</dependency>

是奥齐莫夫
java7 hamcrest匹配器
1.3.0
测试
然后:

@Rule
public ExpectedException thrown = ExpectedException.none();
...
@Test
public void testMethod()
{
    final String errorMessage = "error message";
    Class<? extends Throwable> expectedCause = IllegalStateException.class;
    thrown.expectCause(ExpectedException.exceptionWithMessage(expectedCause, errorMessage));
    someServiceThatTrowsException.foo();
}
@规则
抛出公共ExpectedException=ExpectedException.none();
...
@试验
公共void testMethod()
{
最终字符串errorMessage=“error message”;
课堂总结所有内容

对于JUnit4(hamcrest 1.3,请注意,JUnit4依赖于hamcrest核心,不包括org.hamcrest.beans包)

因此,您需要导入:


org.hamcrest
汉克雷斯特酒店
1.3
测试
代码:

导入静态org.hamcrest.CoreMatchers.*;
导入静态org.hamcrest.beans.HasPropertyWithValue.hasProperty;
@统治
public ExpectedException ExpectedException=ExpectedException.none();
@试验
通过带有CauseAndMessages()的niceException的公共无效测试{
expect(RuntimeException.class);
expectedException.expectMessage(“异常消息”);
expectedException.expectedCause(
全部(
isA(IllegalStateException.class),
hasProperty(“消息”,即(“原因消息”))
)
);
扔
新的运行时异常(“异常消息”,
新的非法状态例外(“原因消息”);
}

您完全可以使用内置的matchers
org.hamcrest.matchers.instanceOf
org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.both;
import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage;

public class temp {
    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    @Test
    public void youCannotDivideByZero() {
        expectedException.expect(RuntimeException.class);
        expectedException.expectMessage(equalTo("Division exception"));
        expectedException.expectCause(both(hasMessage(equalTo("/ by zero"))).and(instanceOf(ArithmeticException.class)));
        divide(1, 0);
    }

    private float divide(int first, int second) {
        try {
            return first / second;
        } catch(ArithmeticException e) {
            throw new RuntimeException("Division exception", e);
        }
    }
}

验证Kotlin语言的消息和引发异常的原因的示例:

@get:Rule
val exceptionRule: ExpectedException = ExpectedException.none()

@Test
fun `test method`() {
    exceptionRule.expect(NestedServletException::class.java)
    exceptionRule.expectMessage("error msg")
    exceptionRule.expectCause(instanceOf(IllegalStateException::class.java))
    // ...

我的意思是你的运行时JUnit版本,你可以试着调试代码。我目前也有同样的问题……对我来说,当我使用从父项目继承的依赖项时,问题就出现了,但现在当我在本地POM.xml中重新声明依赖项时。你找到解决方案了吗???@Dennis,没有。我使用标准的try/catch java习惯用法。如果不会抛出junit fail()。在catch块中,我会分析原因。谢谢。我现在会继续使用复制的依赖项,但会像您所做的那样退回到try-catch块。第二个示例是正确的方法。
shown.expectCause(IsInstanceOf.instanceOf(java.io.IOException.class))
没问题,因为可以推断出该方法的来源:
导入static org.hamcrest.CoreMatchers.isA;
虽然有用,但该问题与Kotlin无关,并且该答案没有解决所问的错误
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.both;
import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage;

public class temp {
    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    @Test
    public void youCannotDivideByZero() {
        expectedException.expect(RuntimeException.class);
        expectedException.expectMessage(equalTo("Division exception"));
        expectedException.expectCause(both(hasMessage(equalTo("/ by zero"))).and(instanceOf(ArithmeticException.class)));
        divide(1, 0);
    }

    private float divide(int first, int second) {
        try {
            return first / second;
        } catch(ArithmeticException e) {
            throw new RuntimeException("Division exception", e);
        }
    }
}
@get:Rule
val exceptionRule: ExpectedException = ExpectedException.none()

@Test
fun `test method`() {
    exceptionRule.expect(NestedServletException::class.java)
    exceptionRule.expectMessage("error msg")
    exceptionRule.expectCause(instanceOf(IllegalStateException::class.java))
    // ...