Mockito 不适用于 HttpURLConnection 的内部方法变量

问题描述 投票:0回答:2

这是编写 junit 的方法

public boolean isSelfServicePortalServerAvailable(String crmEndPoint) {
        boolean isServerAvailable = false;
        URL url = null;
        HttpURLConnection connection = null;
        try {
            url = new URL(crmEndPoint);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            isServerAvailable = true;
            connection.disconnect();
        } catch (MalformedURLException e) {
            log.error(e.getMessage());
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return isServerAvailable;
    }

这是编写的测试用例

@Mock
private URL mockUrl;

@Mock
private HttpURLConnection mockConnection;

@Mock
private ISelfServiceDao selfServiceDao;

@Mock
private RestTemplate restTemplate;

@InjectMocks
private SelfServiceCoreClaimImpl selfServiceCoreClaimImpl = new SelfServiceCoreClaimImpl(restTemplate);



@Test
public void testIsSelfServicePortalServerAvailable_Success() throws IOException {
    
    when(mockUrl.openConnection()).thenReturn(mockConnection);
    doNothing().when(mockConnection).connect();
    doNothing().when(mockConnection).disconnect();

    boolean result = selfServiceCoreClaimImpl.isSelfServicePortalServerAvailable("http://test-url.com");
    assertTrue(result);
}

错误org.mockito.exceptions.misusing.UnnecessaryStubbingException: 检测到不必要的存根。 干净且可维护的测试代码需要零不必要的代码。 以下存根是不必要的(单击以导航到相关代码行):

  1. -> 在 com.acentra.ssp.impl.SelfServiceCoreClaimImplTest.testIsSelfServicePortalServerAvailable_Success(SelfServiceCoreClaimImplTest.java:71)
  2. -> 在 com.acentra.ssp.impl.SelfServiceCoreClaimImplTest.testIsSelfServicePortalServerAvailable_Success(SelfServiceCoreClaimImplTest.java:72)
  3. -> 在 com.impl.SelfServiceCoreClaimImplTest.testIsSelfServicePortalServerAvailable_Success(SelfServiceCoreClaimImplTest.java:73) 请删除不必要的存根更多信息:UnnecessaryStubbingException 类的 javadoc。 在 org.mockito.junit.jupiter.MockitoExtension.afterEach(MockitoExtension.java:192) 在 java.base/java.util.ArrayList.forEach(ArrayList.java:1511) 在 java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

不调用模拟...有人可以帮助我吗

java junit mockito
2个回答
0
投票

我在你的junit中做了一些调整,它运行得很好。

    @Test
    @SneakyThrows
    public void testIsSelfServicePortalServerAvailable_Success() {
        HttpURLConnection mockConnection = Mockito.mock(HttpURLConnection.class);
        URL mockUrl = Mockito.mock(URL.class);
        SelfServiceCoreClaimImpl selfServiceCoreClaimImpl= new SelfServiceCoreClaimImpl();
        Mockito.doReturn(mockConnection).when(mockUrl).openConnection();
        Mockito.doNothing().when(mockConnection).connect();
        Mockito.doNothing().when(mockConnection).disconnect();

        boolean result = selfServiceCoreClaimImpl.isSelfServicePortalServerAvailable("http://test-url.com");
        assertTrue(result);
    }

0
投票

您不能只为方法内创建的对象注入模拟(如

new URL(crmEndPoint);
)。

@InjectMocks
会自动将模拟注入到
private
字段、setter 或构造函数参数中。

如果在方法内部创建对象,则必须考虑以下事项:

  1. 这个对象是无状态的吗?然后我必须从构造函数或 DI 系统接收它,然后模拟它。所以我必须重构该方法并删除新对象的创建。
  2. 这个对象是DTO吗?那我就没必要嘲笑它了。
  3. 如果以上都没有,这意味着无法避免对象创建(据我所知可能是您的情况)那么您必须使用
    MockedConstruction
    。 此外,为了使模拟构造正常工作,您将需要 Maven 中的以下依赖项:
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>some version here</version>
    <scope>test</scope>
</dependency>
© www.soinside.com 2019 - 2024. All rights reserved.