给定,何时,然后约定和异常处理.与Mockito和JUnit



将测试用例分为3个部分是一种很好的做法:Given、When、Then。

但在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);
}
}

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

首先,我认为您的测试是可以的,即使有些测试没有完全遵循给定的/whin/then序列,但如果您想标准化测试的组织以提高可读性,这对您来说是有益的。

有很多有效的方法可以在JUnit中预期异常,如StackOverflow页面中所述。我认为似乎符合给定/何时/当时组织的是:

@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
}

您可以在测试注释中定义期望的异常类型,因此:

@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());
    }
}

我发现这是测试异常处理的一种更好的方法

最新更新