Невозможно использовать насмешку для создания исключения - выброшенное исключение не перехватывается - PullRequest
1 голос
/ 09 апреля 2019

У меня есть метод, в котором я хотел бы смоделировать создаваемое исключение для ввода оператора catch:

public static String func(String val) {
  try {
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    return Base64.encode(md5.digest(val.getBytes()));
  } catch (NoSuchAlgorithmException toCatch) {
      return "*";
  }
}

Тест, который я написал, выглядит так:

@Test
public void testFunc() throws Exception {
  MessageDigest md5 = PowerMockito.mock(MessageDigest.class);
  PowerMockito.when(md5.getInstance(anyString())).thenThrow(new NoSuchAlgorithmException());  
  Assert.assertEquals("*", func("in"));
}

Однако я получаю:

java.security.NoSuchAlgorithmException:  MessageDigest not available

на линии PowerMockito.when().Что подразумевает, что исключение прошло, но не поймано?Что я делаю не так?

Обновление: я попробовал следующие модификации

@PrepareForTest({MessageDigest.class}) 
@Test
public void testFunc() throws Exception {
  PowerMockito.mockStatic(MessageDigest.class); 
  PowerMockito.when(MessageDigest.getInstance(anyString())).thenThrow(new NoSuchAlgorithmException());
  Assert.assertEquals("*", testFunc("in"));
}

Это приводит к запуску функции без вызова исключения.

И это:

@PrepareForTest({MessageDigest.class})
@Test
public void testFunc() throws Exception { 
  PowerMockito.mockStatic(MessageDigest.class);
  MessageDigest md5 = PowerMockito.mock(MessageDigest.class); 
  PowerMockito.doThrow(new NoSuchAlgorithmException()).when(md5, "getInstance", anyString()); 
  Assert.assertEquals("*", func("in"));
} 

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

Ответы [ 3 ]

0 голосов
/ 09 апреля 2019

Поскольку MessageDigest.getInstance () является статическим методом - вы должны подготовить его к тесту и использовать mockStatic ().

Вот хороший пример этого: https://examples.javacodegeeks.com/core-java/powermockito/powermock-mock-static-method-example/

Надеюсь, что поможет

Вот что я написал:


@RunWith(PowerMockRunner.class)
public class MyTest {

    @Test
    @PrepareForTest({MessageDigest.class})
    public void testFunc() throws Exception {
        mockStatic(MessageDigest.class);
        when(MessageDigest.getInstance(anyString())).thenThrow(new NoSuchAlgorithmException());
        assertEquals("*", func("in"));
    }

    public static String func(String val) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            return Base64.encode(md5.digest(val.getBytes()));
        } catch (NoSuchAlgorithmException toCatch) {
            return "*";
        }
    }
}

my pom.xml

<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito</artifactId>
            <version>1.7.4</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>1.7.4</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-core</artifactId>
            <version>1.7.4</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
0 голосов
/ 08 мая 2019

Поскольку MessageDigest является системным классом Java, вам нужно обращаться с ними по-разному в соответствии с: https://github.com/powermock/powermock/wiki/Mock-System

Итак, объявите тестовый класс в аннотации @PrepareForTest следующим образом: @PrepareForTest({MessageDigest.class, MyTest.class})

Не уверен, что эта аннотация работает как уровень метода в соответствии с вашим примером, но она должна быть на уровне класса:

@RunWith(PowerMockRunner.class)
@PrepareForTest({MessageDigest.class, MyTest.class})
public class MyTest {
0 голосов
/ 09 апреля 2019

Инвертирование заглушки:

doThrow(new NoSuchAlgorithmException()).when(md5, "getInstance", anyString())

Создавая его так, как вы это сделали, вы вызываете реальный метод до того, как он заглушается.

...