有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何测试不同异常和结果的方法?

如何在不同的结果和例外情况下实施测试方法

我将代码简化为理解:

public double someCalc(double a, double b, double c) throws ALessThanZeroException, BIsZeroException{
    if (a < 0){
        throw new ALessThanZeroException();
    }

    if (b == 0){
        throw new BIsZeroException();
    }

    return a*b*c;
}

那么,如何在jUnit中验证这个方法呢?我需要创建3个不同的测试吗?或者在这种情况下,我可以结合使用“参数化”和“异常预期”方法吗


共 (3) 个答案

  1. # 1 楼答案

    如果您有自定义的运行时异常(例如,包含状态代码或原因的异常),您可能还需要断言代码/原因。在Junit 5中,您可以执行以下操作:

    @Test
    void someTestMethod(){
    // First case
    YourExceptionType exception = assertThrows(YourExceptionType.class, () -> myService.methodToTest(param1, param2));
    assertThat(exception.getCode(), is(1001));
    
    // Second case
    YourExceptionType exception = assertThrows(YourExceptionType.class, () -> myService.methodToTest(param3, param4));
    assertThat(exception.getCode(), is(1002));
    }
    

    正如您所见,不再需要执行一个测试/异常

  2. # 2 楼答案

    您需要为每种可能的情况创建一种方法。因为你的方法有3个可能的退出点,所以你至少需要3个测试:

    // Check if a is less than 0
    @Test(expected = ALessThanZeroException.class)
    public void throwsALessThanZero_WhenALessZero() {
       yourclass.someCalc(-1.0, 2.0, 30.0);
    }
    
    // Check if a is not less than 0 and b is 0
    @Test(expected = BIsZeroException.class)
    public void throwsBIsZero_WhenAIsNotLessZeroAndBIsZero() {
        yourClass.someCalc(2.0, 0.0., 3.4);
    }
    
    // Test normal situation
    @Test
    public void calculate_WhenAIsNotLessZeroAndBIsNotZero() {
        double a = 2.0;
        double b = 1.0;
        double c = 3.0;
        double res = yourClass.someCalc(a, b, c);
        assertEquals(res, a * b * c);
    }
    
  3. # 3 楼答案

    你可以使用参数化测试来测试它,但老实说,创建3个单独的测试。它更清晰,并且遵循一条规则“只给出一个考试失败的原因”

    所以:

    @Test(expected = ALessThanZeroException.class)
    public void shouldThrowALessThanZero_WhenIncorrectA() {
      //... your logic here
    }
    
    @Test(expected = BIsZeroException.class)
    public void..... and so on
    

    使用JUnit的@Rule还有另一种方法:

    @Rule
    public ExpectedException exceptionRule = ExpectedException.none();
    // ...
    
    @Test
    public void shouldThrowALessThanZero_WhenIncorrectA() {
        exceptionRule.expect(ALessThanZeroException.class);
        exceptionRule.expectMessage("A should be greater than 0.");
        // ...
    }
    

    对于参数化测试,如果我想根据不同的输入测试代码并检查输出,我会使用它。这似乎与你的问题相似,但在你的案例中,你正在测试特定的逻辑,一些特殊的案例。不要将其与“常规”病例混用