Cucumber JVM:测试是否抛出了正确的异常

sam*_*ach 17 cucumber-jvm

如何在使用Cucumber JVM时测试是否抛出了正确的异常?使用JUnit时,我会做这样的事情:

@Test(expected = NullPointerException.class)
public void testExceptionThrown(){
    taskCreater.createTask(null);
}
Run Code Online (Sandbox Code Playgroud)

如您所见,这非常优雅.但是,当使用黄瓜JVM时,我怎样才能达到同样的优雅?我的测试现在看起来像这样:

@Then("the user gets a Null pointer exception$")
public void null_exception_thrown() {
    boolean result = false;
    try {
        taskCreater.createTask(null);
    } catch (NullPointerException e) {
        result = true;
    }
    assertTrue(result);
}
Run Code Online (Sandbox Code Playgroud)

注意需要一个try.. catch后跟assertTrue一个标志.

Nie*_*Wet 11

测试不快乐的路径可能很难.这是一个很好的方式,我发现用黄瓜做到这一点.

Scenario: Doing something illegal should land you in jail
    Then a failure is expected
    When you attempt something illegal
    And it fails.
Run Code Online (Sandbox Code Playgroud)

好吧,不要拍我,因为我把它放在Then前面When,我只是认为它读得更好但你不必这样做.

我将我的异常存储在(黄瓜范围的)世界对象中,但您也可以在步骤文件中执行此操作,但这将限制您以后的操作.

public class MyWorld {
    private boolean expectException;
    private List<RuntimeException> exceptions = new ArrayList<>();

    public void expectException() {
        expectException = true;
    }

    public void add(RuntimeException e) {
        if (!expectException) {
            throw e;
        }
        exceptions.add(e);
    }

    public List<RuntimeException> getExceptions() {
        return exceptions;
    }
}
Run Code Online (Sandbox Code Playgroud)

您的步骤非常简单:

@Then("a failure is expected")
public void a_failure_is_expected() {
    myWorld.expectException();
}
Run Code Online (Sandbox Code Playgroud)

在您(至少有时)期待异常的步骤中,抓住它并将其添加到世界中.

@When("you attempt something illegal")
public void you_attempt_something_illegal() {
    try {
        myService.doSomethingBad();
    } catch (RuntimeException e) {
        world.add(e);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以检查是否在世界中记录了异常.

@And("it fails")
public void it_fails() {
    assertThat(world.getExceptions(), is(not(empty()));
}
Run Code Online (Sandbox Code Playgroud)

这种方法最有价值的地方在于,当你不期望它时,它不会吞下异常.

  • 我喜欢这种方法,我认为这行`} catch(RuntimeException e){`可以替换为`} catch(YourExpectedException e){`所以如果抛出你不期望的异常,测试将会失败 (4认同)

小智 7

您是否尝试过使用带有ExpectedException的junit @Rule注释,如下所示:

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

@Then("the user gets a Null pointer exception$")
public void null_exception_thrown() {
    expectedEx.expect(NullPointerException.class);
    //expectedEx.expectMessage("the message");
    taskCreater.createTask(null);
}
Run Code Online (Sandbox Code Playgroud)

  • 这真的有用吗?据此,它没有效果:https://github.com/cucumber/cucumber-jvm/issues/393 (4认同)

Tar*_*rek 5

行为测试验证您的项目是否遵循规范,我怀疑用户在使用系统时是否期望NullPointerException.

在我看来(我不熟悉你的项目),只应在单元测试期间检查异常,因为它们对应于意外错误或用户错误.

在行为测试期间检查异常是非常不寻常的.如果在测试期间抛出异常,则应该失败.

例如:

test.feature

Given that I have a file "users.txt"
And I try to import users /* If an Exception is thrown here, the test fails */
Then I should see the following users: /* list of users */
Run Code Online (Sandbox Code Playgroud)

在我的单元测试中,我会:

@Test(expected = MyException.class)
public void importUsersShouldThrowMyExceptionWhenTheFileIsNotFound() {
    // mock a call to a file and throw an exception
    Mockito.when(reader.readFile("file.txt").thenThrow(new FileNotFoundException());

    importer.importUsers();
}
Run Code Online (Sandbox Code Playgroud)

  • '用户'不一定是人.测试使用的输入接口可以是API. (2认同)

Dav*_*veH 3

从来没有用过黄瓜,但会

    public void null_exception_thrown() {
            try {
                  taskCreater.createTask(null);
                  fail("Null Pointer Expected");
            } catch (NullPointerException e) {

                // Do Nothing
             }
        }
Run Code Online (Sandbox Code Playgroud)

为你工作?