无法使用模拟引发异常-未捕获引发的异常

时间:2019-04-09 11:58:33

标签: java unit-testing junit mocking powermockito

我有一个方法可以模拟抛出的异常,以便输入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 :(得分:0)

反转存根

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

通过像以前一样创建它,可以在存根之前调用实际方法。

答案 1 :(得分:0)

由于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 "*";
        }
    }
}

我的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>

答案 2 :(得分:0)

由于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 {