如何使用 mockito 和 junit 测试此功能?

Posted

技术标签:

【中文标题】如何使用 mockito 和 junit 测试此功能?【英文标题】:How do I test this function using mockito and junit? 【发布时间】:2021-11-06 00:16:28 【问题描述】:

我是 mockito 和 junit5 的新手。我正在尝试测试以下功能:

public boolean checkFunction(String element) 

        CloseableHttpClient client = HttpClients.createDefault();
        String uri = "any url im hitting";
    
        HttpPost httpPost = new HttpPost(uri);

        String json = element;

        StringEntity entity;

        try 
            entity = new StringEntity(json);
            httpPost.setEntity(entity);
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Authorization", "any token");

            CloseableHttpResponse response = client.execute(httpPost);
            String responseBody = EntityUtils.toString(response.getEntity());
            client.close();

            if (responseBody.contains("any string i wanna check"))
                return true;
         catch (Exception e) 
            return false;
        
        return false;
    

我尝试了以下代码,但无法获得整个代码覆盖率。另外我认为这不是正确的方法。

@Test
    public void testCheckFunction() throws Exception 
        when(mockClass.checkFunction(Mockito.anyString())).thenReturn(false);
        assertEquals(false, mockclass.checkFunction("dummy"));
    

谁能帮我解决这个问题? 谢谢!

【问题讨论】:

您不是在测试checkFunction,而是在模拟它,然后测试模拟......相反,您需要实例化真实对象并仅模拟它的依赖项(http 客户端的东西) . @slauth 所以你的意思是我应该把我的模拟类和我的原始类一样对待,并在我的测试中实例化我在原始类中使用的对象?你能用演示代码给我看看吗? 【参考方案1】:

首先你必须重构你的代码以获得更好的可测试性:

public class Checker 

    private final CloseableHttpClient client;

    public Checker(CloseableHttpClient client) 
        this.client = client;
    

    public boolean checkFunction(String element) 

        String uri = "http://example.com";

        HttpPost httpPost = new HttpPost(uri);

        String json = element;

        StringEntity entity;

        try 
            entity = new StringEntity(json);
            httpPost.setEntity(entity);
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Authorization", "any token");

            CloseableHttpResponse response = client.execute(httpPost);
            String responseBody = EntityUtils.toString(response.getEntity());
            client.close();

            if (responseBody.contains("any string i wanna check"))
                return true;
         catch (Exception e) 
            return false;
        
        return false;
    

请注意,依赖项(即必须在测试中模拟的东西)现在是通过构造函数注入的。这样在对这个类进行单元测试时,它可以很容易地被模拟替换:

class CheckerTest 

    private final CloseableHttpClient clientMock = Mockito.mock(CloseableHttpClient.class);

    private final Checker checker = new Checker(clientMock);

    @Test
    public void testCheckFunction() throws Exception 
        when(clientMock.execute(any(HttpPost.class))).thenThrow(new RuntimeException("Oops!"));
        assertFalse(checker.checkFunction("dummy"));
    

【讨论】:

以上是关于如何使用 mockito 和 junit 测试此功能?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用mockito和junit为Java中的ExecutorService编写测试用例?

如何使用junit和mockito为私有void方法编写测试用例[重复]

如何使用 mockito 为以下代码编写 junit 测试?

当我们有 rowmapper 时,如何使用 mockito 编写 junit 测试用例?

测试类时,使用 Junit 和 Mockito 检查方法内部的工作

如何使用 Junit + Mockito 实践单元测试