如何在Cucumber中编写触发NumberFormatException的非法输入测试用例?
在 Cucumber 中处理预期异常的思路和 JUnit 直接加注解的方式不太一样,咱们得把异常断言融入到步骤定义里。下面分两部分给你讲具体实现:
1. Feature 文件的写法
你不需要在 Examples 的 result 列填计算结果,而是要明确场景的预期是「抛出特定异常」。这里有两种写法,看你需求选:
写法一:固定预期异常(所有用例都是 NumberFormatException)
如果你的非法输入用例只会触发这一种异常,场景可以写得更简洁:
Feature: 加法计算异常处理 Scenario Outline: 输入非法格式数值时触发NumberFormatException Given 我准备进行加法计算 When 我输入第一个数为 <num1>,第二个数为 <num2> Then 系统应该抛出NumberFormatException异常 Examples: | num1 | num2 | | "é3-3"| "5" | | "aB" | "10" |
写法二:支持多类型异常(如果以后要加其他异常用例)
如果后续可能测试其他异常类型,可以在 Examples 里加一列指定预期异常的全类名:
Feature: 加法计算异常处理 Scenario Outline: 输入非法值时抛出对应异常 Given 我准备进行加法计算 When 我输入第一个数为 <num1>,第二个数为 <num2> Then 应该抛出 <expectedException> 异常 Examples: | num1 | num2 | expectedException | | "é3-3"| "5" | java.lang.NumberFormatException | | "aB" | "10" | java.lang.NumberFormatException |
2. 胶水代码(Step Definitions)的实现
核心是用 JUnit 的断言工具来捕获并验证异常,推荐用 JUnit 5 的 Assertions.assertThrows(比 JUnit 4 的规则更直观):
对应写法一的步骤代码
import org.junit.jupiter.api.Assertions; import io.cucumber.java.en.Given; import io.cucumber.java.en.When; import io.cucumber.java.en.Then; public class AdditionStepDefs { private String num1; private String num2; @Given("我准备进行加法计算") public void initAddition() { // 初始化状态,清空之前的输入 num1 = null; num2 = null; } @When("我输入第一个数为 {string},第二个数为 {string}") public void inputNumbers(String num1, String num2) { this.num1 = num1; this.num2 = num2; } @Then("系统应该抛出NumberFormatException异常") public void verifyNumberFormatException() { // 直接断言执行加法时会抛出NumberFormatException NumberFormatException exception = Assertions.assertThrows(NumberFormatException.class, () -> add(num1, num2)); // 可选:还可以验证异常消息,比如检查是否包含非法输入的提示 // Assertions.assertTrue(exception.getMessage().contains(num1)); } // 你的加法业务方法(和你原来的代码一致) private int add(String num1, String num2) { int a = Integer.parseInt(num1); int b = Integer.parseInt(num2); return a + b; } }
对应写法二的步骤代码
如果要支持多异常类型,只需要修改 Then 步骤:
@Then("应该抛出 {string} 异常") public void verifySpecificException(String exceptionClassName) throws ClassNotFoundException { Class<?> expectedExceptionClass = Class.forName(exceptionClassName); // 断言抛出的异常类型匹配 Exception exception = Assertions.assertThrows((Class<? extends Exception>) expectedExceptionClass, () -> add(num1, num2)); }
关键说明
- 不要试图在 Cucumber 步骤方法上直接加 JUnit 的
@Test(expected=...),Cucumber 不会识别这个注解。 - 用
assertThrows是最简洁的方式,它会自动验证代码块是否抛出了预期的异常,如果没抛出或者抛出了其他异常,测试就会失败。 - 如果你的业务逻辑是在其他类里(比如一个
Calculator服务类),只需要把add方法替换成调用服务类的方法就行,逻辑完全一致。
内容的提问来源于stack exchange,提问作者S12000
相关产品推荐
相关产品推荐

