Java 给定、when、then约定以及异常处理。与莫基托和朱尼特

Java 给定、when、then约定以及异常处理。与莫基托和朱尼特,java,junit,tdd,junit4,bdd,Java,Junit,Tdd,Junit4,Bdd,将测试用例分为3个部分是一个很好的实践:给定、何时、然后 但在JUnit中,处理异常的常用方法是使用ExpectedException@Rule 问题是ExpectedException::expect()必须在//when节之前声明 public class UsersServiceTest { // Mocks omitted @Rule public ExpectedException thrown = ExpectedException.none(); @Test publ

将测试用例分为3个部分是一个很好的实践:给定、何时、然后

但在JUnit中,处理异常的常用方法是使用ExpectedException@Rule

问题是ExpectedException::expect()必须在//when节之前声明

public class UsersServiceTest {

// Mocks omitted    

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

@Test
public void signUp_shouldCheckIfUserExistsBeforeSign() throws ServiceException {
    // given - its ok
    User user = new User();
    user.setEmail(EMAIL);
    when(usersRepository.exists(EMAIL)).thenReturn(Boolean.TRUE);

    // then ???
    thrown.expect(UserAlreadyExistsServiceException.class);

    // when???
    usersService.signUp(user);

}
}

有人知道一些好的约定或库,可以更好地处理测试中的异常吗?

您可以在测试注释中定义期望的异常类型,如下所示:

@Test(expected=NullPointerException.class)
public void npeThrownWhenFooIsNull() {
    String foo = null;
    foo.contains("nothing");
}
或者,如果要检查引发的异常的详细信息:

@Test
public void npeIsThrownAndContainsNullMessageWhenFooIsNull() {
    String foo = null;
    try {
        foo.contains("nothing");
        fail();
    } catch (NullPointerException npe) {
        assertNull(npe.getMessage());
    }
}

我发现这是一种更好的测试异常处理的方法首先,我认为您的测试是可以的,即使有些测试没有完全遵循给定的/when/then顺序,但是如果您想要标准化测试的组织以提高可读性,这对您是有好处的

在JUnit中有许多有效的方法可以预期异常,如中所述。我认为似乎与给定/何时/当时的组织相适应的是:

@Test
public void signUp_shouldCheckIfUserExistsBeforeSign() throws ServiceException {

    // GIVEN
    User user = new User();
    user.setEmail(EMAIL);
    when(usersRepository.exists(EMAIL)).thenReturn(Boolean.TRUE);

    // WHEN 
    try {
        usersService.signUp(user);

    // THEN
        // expecting exception - should jump to catch block, skipping the line below:
        Assert.fail("Should have thrown UserAlreadyExistsServiceException");         
    }catch(UserAlreadyExistsServiceException e) {
        // expected exception, so no failure
    }
    // other post-sign-up validation here
}

我不确定你的问题是什么。你们想要什么作为最终目标?问题是我在调用测试方法(when节)之前声明异常检查(然后是节)。我在问如何以最好的方式做到这一点。定义“最佳”。我不认为这里有问题。根据TDD/BDDAN的最佳约定/实践,另一个想法是在给定的部分中声明抛出的.expect()。但我们不知道是哪一行导致了问题。这就是为什么人们使用@ruleandwe提供建议的原因,我们无法检查异常的消息或其他属性。如果您不需要它,则“预期”是可以的,否则它有点原始。