Перемешивание MessageDigest.getInstance (), чтобы вызвать исключение - PullRequest
2 голосов
/ 19 мая 2011

Я получил следующий метод:

private MessageDigest getMessageDigest() {
    try {
        return MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
        throw new Error(e);
    }
}

Чтобы получить 100% покрытие кода, мне нужно попасть в блок catch.Но я абсолютно не уверен, как я могу это сделать.Есть ли какие-то насмешливые рамки, которые могут помочь мне в этом случае?Если так - как?Или есть даже другой способ без необходимости ловить исключение?

Ответы [ 5 ]

2 голосов
/ 19 мая 2011

Метод getInstance в MessageDigest выглядит как статический метод.Статические методы не могут быть высмеяны.Я согласен с трещоткой, что вы не должны стремиться к 100% охвату кода, а сосредоточиться на тестировании областей со сложным кодом.

1 голос
/ 07 октября 2013

Просто для продолжения этого вопроса это можно сделать с помощью PowerMock .

В качестве выдержки, это мой рабочий код:

@RunWith(PowerMockRunner.class)
@PrepareForTest({MyClass.class, MessageDigest.class})
public class MyClassTest {

    private MyClass myClass = new MyClass();
    @Mock private MessageDigest messageDigestMock;

    @Test
    public void shouldDoMethodCall() throws Exception {
        setupMessageDigest();

        String value = myClass.myMethodCall();

        // I use FestAssert here, you can use any framework you like, but you get
        // the general idea
        Assertions.assertThat(value).isEqualToIgnoringCase("hashed_value");
    }

    public void setupMessageDigest() throws Exception {
        PowerMockito.mockStatic(MessageDigest.class);
        when(MessageDigest.getInstance("SHA1")).thenReturn(messageDigestMock);
        when(messageDigestMock.digest(Matchers.<byte[]>anyObject())).thenReturn("hashed_value".getBytes());
    }

}

Класс "MyClass" будет просто делать что-то вроде:

public class MyClass {

    public String myMethodCall() {

        return new String(MessageDigest.getInstance("SHA1").digest("someString".getBytes()));

    }        

}

В дополнительном тесте вы можете написать

when(MessageDigest.getInstance("SHA1")).thenThrow(new NoSuchAlgorithmException());

вместо моего упомянутого возвращения, чтобы добраться до вашего блока catch.

Однако обратите внимание, что использование PowerMock имеет некоторые недостатки. Как правило, он будет использовать больше памяти и больше времени, поэтому ваш тест будет работать дольше. Для этого конкретного теста это не будет иметь большого значения, но просто как голова.

1 голос
/ 19 мая 2011

Честно говоря, в этом случае вам не нужно покрывать этот код, это недостижимый шаблон, чтобы вам не пришлось беспокоиться о проверенных исключениях в коде пользователя (в большинстве случаев достаточно 98% покрытия, если вы можете объяснитьпочему пропали 2 процента)

0 голосов
/ 19 мая 2011

Ваше исключение недоступно, потому что это исключение никогда не будет выброшено.Я полагаю, логично что-то вроде Mockito сделать что-то похожее на:

doThrow(new NoSuchAlgorithmException()).when(MessageDigest.getInstance("MD5")); // this is psuedo code

Но это все равно не имеет особого смысла.Вам лучше написать свой код, например:

private static final MessageDigest MD5_DIGEST;
static {
   try {
      MD5_DIGEST = MessageDigest.getInstance("MD5");
   ///CLOVER:OFF
   } catch (Exception e) {
      // can't happen since MD5 is a known digest
   }
   ///CLOVER:ON
}

public MessageDigest getMessageDigest() {
   return MD5_DIGEST;
}

, в противном случае вам нужно будет изменить метод для проверки:

public MessageDigest getMessageDigest(String digest) throws NoSuchAlgorithmException {
   return MessageDigest.getInstance(digest);
}
0 голосов
/ 19 мая 2011

Я бы написал это как:

try {
    return MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
    throw (AssertionError)new AssertionError("unreachable").initCause(e);
}

И объявил бы, что поскольку блок catch недоступен, его не нужно тестировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...