当前位置: 首页 > 知识库问答 >
问题:

使用spy进行mockito更好的预期异常测试

芮承运
2023-03-14

如何进行第三个测试来检查异常消息中原因1的存在?我还列出了前两个测试中存在的缺点。首先是不检查消息,其次需要大量样板代码。

public class CheckExceptionsWithMockitoTest {

    @Test(expected = RuntimeException.class)
    public void testExpectedException1() {
        A a = new A();
        a.doSomethingThatThrows();
    }

    @Test
    public void testExpectedException2() {
        A a = new A();
        try {
            a.doSomethingThatThrows();
            fail("no exception thrown");
        } catch (RuntimeException e) {
            assertThat(e.getMessage(), org.hamcrest.Matchers.containsString("cause1"));
        }
    }

    @Test
    public void testExpectedException3() {
        A a = new A();
        A spyA = org.mockito.Mockito.spy(a);
        // valid but doesnt work
        // doThrow(new IllegalArgumentException()).when(spyA).doSomethingThatThrows();
        // invalid but in the spirit of what i want 
        //chekThrow(RuntimeException.class,containsString("cause1")).when(spyA).doSomethingThatThrows();
    }

}

我在Mockito中找不到一些有用的东西,但有一些东西看起来是可能的(在语法级别)和功能。

使用catchexception,我创建了这样的测试

import static com.googlecode.catchexception.CatchException.*;
import static com.googlecode.catchexception.apis.CatchExceptionHamcrestMatchers.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

import org.junit.*;
public class CheckExceptionsWithMockitoTest{  
    //...
    @Test
    public void testExpectedException3() {
        A a = new A();
        verifyException(a,IllegalArgumentException.class)
            .doSomethingThatThrows();
        //if more details to be analized are needed
        assertThat(
            (IllegalStateException) caughtException(),
            allOf(
                is(IllegalStateException.class),
                hasMessageThat(
                        containsString("is not allowed to add counterparties")), 
                hasNoCause()));
        //more asserts could come
        assertNotNull(a);
    }
}

共有3个答案

高慈
2023-03-14

如果您有机会使用scala,calaTest的有趣套件有使用拦截(http://www.scalatest.org/getting_started_with_fun_suite)测试异常的简明方法。

它就像

  test(a list get method catches exceptions){
    intercept[IndexOutBoundsException]{
      spyListObject.get(-1)
    }
  }

如果你正在寻找易于编写/清除的测试,你可以用scala编写你的测试到你的java项目中。但这可能会带来其他挑战。

单于钊
2023-03-14

如果A是你被测的系统,那么嘲笑它没有任何意义,监视它也很少有意义。您在测试中的实现异常2是正确的;样板代码是必要的,因为如果没有try块,Java在方法被拦截后不会让任何代码运行(正如我在前面的SO答案中描述的那样)。

虽然Mockito帮不了什么忙,但JUnit会的。@Test(expected=foo)html" target="_blank">参数实际上有一个更灵活的替代方法,即内置的ExpectedExceptionJUnit规则:

public class CheckExceptionsWithMockitoTest {

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

  @Test
  public void testExpectedException1() {
    A a = new A();
    thrown.expect(RuntimeException.class);
    thrown.expectMessage(containsString("cause1"));
    a.doSomethingThatThrows();
  }
}

Mockito将在单独的测试中派上用场,检查您的方法是否在保留其消息的同时包装任意异常,如下所示:

@Test
public void doSomethingShouldWrapExceptionWithPassedMessage() {
  Dependency dependency = Mockito.mock(Dependency.class);
  when(dependency.call()).thenThrow(new IllegalArgumentException("quux"));
  A a = new A(dependency);
  thrown.expect(RuntimeException.class);
  thrown.expectMessage(containsString("quux"));
  a.doSomethingThatThrows();
}

小心避免在测试中使其成为常见模式的诱惑。如果您正在捕获从被测系统中抛出的异常,您实际上是在将控制权交还给SUT的消费者。之后在方法中应该没有什么可测试的了,除了异常的属性和系统的状态,这两者都应该足够罕见,可以原谅try/catch样板文件。

贲骏喆
2023-03-14

使用捕获异常库,或者我猜你正在寻找的解决方案是你的第二个实现。

@expected除了它的类之外,没有提供任何方法来断言抛出的异常,所以你不能avoit尝试/捕获(没有那么多的样板代码!

Mockito不提供类似verifyThrows方法的东西。

因此,您可以用 try/catch 换取一个额外的库:使用 catch-exception,您将能够在一行中捕获异常,并为进一步的断言做好准备。

A a = new A();

when(a).doSomethingThatThrows();

then(caughtException())
        .isInstanceOf(IllegalStateException.class)
        .hasMessageContaining("is not allowed to add counterparties")
        .hasNoCause();
'com.googlecode.catch-exception:catch-exception:1.2.0'
 类似资料:
  • 我正在使用和Spy对函数进行单元测试。 这是正在测试的类: 我正在尝试使用Mockito和spy进行测试,因为我不想调用真正的函数只需验证一下即可。该测试称为 这是错误: 我也尝试过这样做,它会导致空指针:

  • 我尝试为Spring Boot应用程序的以下服务类编写一个JUnit测试用例。 我试图用这个测试用例覆盖尽可能多的行 我认为语句“myService.myMethod(vetResp,req);”将运行真正的方法,因为myService用@Spy注释。但SonarQube扫描报告显示,该方法没有涵盖任何一行。 我是新来的。有人能告诉我我做错了什么吗?谢谢! 谢谢大家的投入。我用@InjectMoc

  • 主要内容:1. 运行时异常,2. 检查异常在本教程中,我们将演示如何使用TestNG expectedExceptions来测试代码中的预期异常抛出。 创建一个名称为 ExpectedExceptionTest 的 Maven 工程,其结构如下所示 - 1. 运行时异常 此示例显示如何测试运行时异常。 如果方法抛出一个运行时异常 — ,它会获得通过。 创建一个测试文件:TestRuntime.java ,其代码如下所示 - 运行上面代码,

  • 我使用JUnit4和Mockito创建了一个Spring Boot2应用程序。当我测试某种方法时。会出现这样的例外: 这是我的测试代码 SuveryService.java SurveyRepository.java 我引用了这篇文章Mockito NullPointerException,但这个问题仍然存在。任何帮助都将被应用。

  • 我应该如何测试异常?我可以mock connector并且我可以赋予它抛出异常的行为,但是我不明白下一步该怎么做。

  • 在实用服务中,我有两个功能foo和bar。js 在我的测试文件中,我导入了实用ervice.js并窥探了条形图函数。我期望调用间谍计数为1,因为foo被称为,但它是0。如果我错过了什么,请建议。