测试异常未被抛出。

3

我正在创建一项集成测试:

@RunWith(CdiRunner.class)
@AdditionalClasses({FollowUpActivityRepository.class, SettingsPropertiesProducer.class})
public class FollowUpActivityFeaturesTest {

  @Inject protected FollowUpActivityService fuaService;

  @Test
  public void DigitalInputTOFollowUpActivityFIELDS()
  { 
    FollowUpActivityDTO dto = new FollowUpActivityDTO();
    dto.setId("id");
    dto.setTimestamp(Date.from(Instant.now()));
    dto.setDueTimestamp(Date.from(Instant.now()));
    dto.setClosingTimestamp(Date.from(Instant.now()));
    dto.setMatter("matter");
    dto.setComment("comment");

    this.fuaService.createOrUpdate(dto); 

  }

}

createOrUpdate的作用类似于:

public void createOrUpdate(FollowUpActivityDTO dto) throws RepositorySystemException

所以,我需要检查此异常是否被抛出。

我想要优雅地完成它。

实际上,我正在使用junit 4.12和hamcrest 2.0.0.0。

有什么想法吗?

示例

在.NET中,我正在使用NSubstitute来实现:

this.apiClient.Invoking(c => c.GrantAuthorization()).ShouldNotThrow();
1个回答

3
如果你想让测试在抛出异常时失败,那么你只需要在测试方法签名的throws部分声明一个异常即可(如果抛出的异常是一种RuntimeException,则不是必须的,但显然你的异常不是这种类型)。
public void DigitalInputTOFollowUpActivityFIELDS() throws Exception

不需要指定任何类型的异常。无论如何,只要抛出未经处理的异常(这是您期望的行为),任何jUnit测试都将失败。
来自于这篇博客
引用: 声称它们抛出一种特定类型的异常的测试方法容易出错,因为一旦被测试的方法发生改变,它们就必须被修改。
原回答: 只需像这样编写您的测试注释:
@Test(expected=RepositorySystemException.class)

这样,只要抛出这个异常,测试方法就会成功。
参见 javadoc编辑 您的评论后:

要针对任何异常验证测试,只需:
@Test(expected=Exception.class)

但是正如B. Dalton所建议的那样,这似乎有点危险,因为这个测试将会通过任何异常,无论它是你期望的还是其他任何异常。

为了完整起见,你也可以像这样做(基于这个答案):

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

@Test
public void DigitalInputTOFollowUpActivityFIELDS()
{ 
    FollowUpActivityDTO dto = new FollowUpActivityDTO();
    dto.setId("id");
    dto.setTimestamp(Date.from(Instant.now()));
    dto.setDueTimestamp(Date.from(Instant.now()));
    dto.setClosingTimestamp(Date.from(Instant.now()));
    dto.setMatter("matter");
    dto.setComment("comment");

    thrown.expect(Exception.class);
    thrown.expectMessage("something you can check"); // if needed

    this.fuaService.createOrUpdate(dto); 
}

这样,createOrUpdate仍然可以通过抛出任何类型的异常来验证测试,但至少方法的其余部分不会受影响。
请参阅ExpectedException的Java文档。
或者,当然,还有传统的解决方案:
try {
    this.fuaService.createOrUpdate(dto); 
    fail("this should throw an exception");
} catch (RepositorySystemException e){
    // pass
} catch (Exception e){
    // pass
}

这样做不太优雅,但您可以根据需要调整异常处理方式。


我需要检查是否抛出了任何异常。 - Jordi
我需要检查现在是否抛出了这个异常。那不是你要求的,但请看编辑后的答案。 - xlecoustillier
1
Jordi,我很难想象如果抛出 任何 异常,这个测试应该会成功。你确定如果抛出 NullPointerException,你想让这个测试通过吗? - Breandán Dalton
@B.Dalton 很好的观点,我已经把它加入了回答中,希望你不介意。 - xlecoustillier
啊!我打错字了。我已经更正了。我的意思是“我需要检查是否没有抛出任何异常”。对我来说麻烦的是,this.fuaService.createOrUpdate(dto) 可能会抛出 RepositoryException 异常,而 Java 编译器告诉我需要在测试方法签名中添加 try/catch 或者添加一个 throws declaration。对不起!我在帖子中添加了一个使用 NSubstitute 的示例。 - Jordi
@Jordi 嗯...已编辑。在SO上更改问题的含义是一种不好的做法,因为这会使现有答案失效。 - xlecoustillier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接