繁体   English   中英

如何在 JUnit 中为 Java 程序编写异常测试?

[英]How can I write exception test for a Java program in JUnit?

package BasicTesting;

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Factorial_of_number {
    public static int factorial(int n)//factorial method
    {
        if (n == 0) {
            return 1;
        } else if (n < 1) {
            return -1;
        } else {
            return n * factorial(n - 1);
        }
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("Enter number to factorize ");
        int n = input.nextInt();
        System.out.println(factorial(n));
    }
}

在这里,当我们将负数作为输入时,它们并没有得到很好的处理。 实际上,程序应该返回我们找不到负数的阶乘。 通过使用这个程序,我们如何编写 JUnit 测试用例来检查程序是否给出正确的负数输出? 他们不检查负数,所以在我们测试异常时系统一定会失败,对吧? 我也附上了我的 JUnit 测试用例。

package BasicTesting;

import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.Collection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)

public class FactorialTest {

    public FactorialTest(int input, int expected) {
        super();
        this.input = input;
        this.expected = expected;
    }

    Factorial_of_number ob = new Factorial_of_number();
    private int input;
    private int expected;

    @Parameters
    public static Iterable<Object[]> testConditions() {
        return Arrays.asList(new Object[][]{{0, 1}, {1, 1},
                {5, 120}, {-3, -1}, {10, 3628800}, {12, 479001600}});
    }

    @Test
    public void factorial_test() {
        assertEquals(expected, Factorial_of_number.factorial(input));
    }
}

如何检查该异常? 我也应该更改我的源程序吗? 还请提供编辑后的代码。

首先,当您当前返回 -1 时,您的阶乘方法将抛出负值异常,因此您的方法将如下所示 -

    public static int factorial(int n)//factorial method
{
    if (n == 0) {
        return 1;
    } else if (n < 1) {
        throw new RuntimeException("Negative value, can not get factorial");
    } else {
        return n * factorial(n - 1);
    }
}

然后你可以有这样的测试用例 -

@RunWith(Enclosed.class)
public class FactorialTest {
@RunWith(Parameterized.class)
public static class GoodTest {
    @Parameters
    public static Iterable<Object[]> goodTestConditions() {
        return Arrays.asList(new Object[][]{{0, 1}, {1, 1},
                {5, 120}, {10, 3628800}, {12, 479001600}});
    }


    public GoodTest(int input, int expected) {
        this.input = input;
        this.expected = expected;
    }

    private final int input;
    private final int expected;


    @Test
    public void factorial_test_good() {
        assertEquals(expected, Factorial_of_number.factorial(input));
    }
}

@RunWith(Parameterized.class)
public static class BadTest {
    @Parameters
    public static Iterable<Object[]> badTestConditions() {
        return Arrays.asList(new Object[][]{{-1}, {-10}});
    }


    public BadTest(int input) {
        this.input = input;
    }

    private final int input;


    @Test(expected = RuntimeException.class)
    public void factorial_test_good() {
        Factorial_of_number.factorial(input);
    }
}
}

首先,您必须声明在您的测试方法中何时以及什么类型的异常被抛出。

然后,对于 JUnit4,有 3 种主要方法来断言抛出异常。

1)非常原始和不优雅的方式:

这是基本的方法,但仍然可用。

@Test    
public void factorial_test_good() {
   try {
       Factorial_of_number.factorial(input);
   } catch(Exception e) {
       Assert.assertThat(e, Matchers.<Exception>instanceOf(YourException.class));
   }
}

2) 快速易读:

如果您想识别失败的测试,但不需要详细信息,则最好。

@Test(expected = YourException.class)
public void factorial_test_good() {
    Factorial_of_number.factorial(input);
}

3) 最复杂,最适合详细测试

如果您想测试特定场景,例如异常消息或原因,请使用此选项。 可能有一种方法会引发具有不同类型或消息的多个异常 - 那么这是最佳选择。

在测试注释之前初始化:

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

测试自己:

@Test    
public void factorial_test_good() {
   exceptionRule.expect(YourException.class);
   /* 
    * OPTIONAL
    * exceptionRule.expectMessage("Your custom exception message");
    * exceptionRule.expectCause(is(instanceOf(IllegalStateException.class)));
    */
   Factorial_of_number.factorial(input);
}

我想这远远超出了您的问题,但将来会很方便。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM