0

我正在测试一种引发两个不同异常的方法。这是我的标题:

@Test (expected = A8InvalidInputException.class)
public void testGuessCharacter() throws A8InvalidInputException, A8AlreadyGuessedException { ... }

正文有两个 try/catch 块(对 SO 的搜索导致一篇帖子说这是您测试抛出异常的方式),一个用于每个异常。在我看来,我应该把它分成两种测试方法,特别是因为我只能有一个预期的属性。但是,当我这样做时,应该测试 A8InvalidInputException 的方法需要 A8AlreadyGuessedException 的 try/catch,而应该测试 A8AlreadyGuessedException 的方法需要 A8InvalidInputException 的 try/catch。我不确定如何编写这个测试。这是我正在尝试测试的方法:

/**
 * This method returns whether a specified character exists in the keyPhrase field
 * @param guess  a character being checked for in the keyPhrase field
 * @return  returns whether a specified character exists in the keyPhrase field
 * @throws A8InvalidInputException  if a non-valid character is passed as input to this method
 * @throws A8AlreadyGuessedException  if a valid character which has already been guessed is passed as input to this method
 */
public boolean guessCharacter(char guess) throws A8InvalidInputException, A8AlreadyGuessedException
{
    if(isValidCharacter(guess))
    {
        guess = Character.toLowerCase(guess);

        if(guessedCharacters.contains(guess) )
        {
            throw new A8AlreadyGuessedException("" + guess);
        }
        else
        {
            guessedCharacters.add(guess);
            if(keyPhrase.contains("" + guess))
                return true;
            else
            {
                numberOfGuessesLeft--;
                return false;
            }
        }       
    }
    else
    {
        throw new A8InvalidInputException("" + guess);
    }
}
4

4 回答 4

6

只需在 throws 子句中添加两个异常:

@Test (expected = A8InvalidCharacterException.class) 
public void testInvalidCharacterScenario() throws A8InvalidInputException, A8AlreadyGuessedException { ... }

@Test (expected = A8InvalidInputException.class) 
public void testInvalidInputScenario() throws A8InvalidInputException, A8AlreadyGuessedException { ... }

然后,如果一个测试抛出另一个异常(意外的异常),那么您的测试将自动失败。

于 2013-03-09T22:42:03.637 回答
4

一个方法在运行时只能抛出一个异常。这就是为什么只能有一个预期属性。

您可能需要三个测试用例:一个是方法抛出一个异常,一个是该方法抛出另一个异常,一个是该方法根本没有抛出任何异常。

不要在您的@Test方法中放置任何 try/catch 语句,只需声明它们抛出异常即可。

于 2013-03-09T22:43:16.770 回答
2

是的,你应该把它分成两个单元测试。一个带有无效输入来触发A8InvalidInputException,另一个带有“已经猜到”输入来触发A8AlreadyGuessedException.

于 2013-03-09T22:40:06.180 回答
1

考虑一下,为了使编写测试更简单,将它们分成两个不同的部分——分别进行测试isValidCharacter和测试guessCharacter

假设isValidCharacter(guess)如果您收到无效的猜测,这将失败,我认为A8InvalidInputException采用该方法将是理想的。

public boolean isValidCharacter(char guess) throws A8InvalidInputException {
    // have your logic to check the guess, and if it's invalid, throw
}

然后您需要做的就是测试特定方法以查看它是否在虚假输入上引发异常。

@Test (expected = A8InvalidInputException.class)
public void testIsValidCharacterWithInvalidCharacter() {
    // write your test here.
}

接下来,您可以将您的方法更改为只关​​心该方法的快乐路径isValidCharacter,因为如果您不返回布尔值,您就会抛出异常。

最后,您只关心guessCharacter是否抛出A8AlreadyGuessedException.

@Test (expected = A8AlreadyGuessedException.class)
public void testGuessCharacterWithAlreadyGuessedValue() {
    // write your test here.
}
于 2013-03-09T22:59:14.123 回答