繁体   English   中英

Mockito mocking 数据库调用

[英]Mockito mocking database calls

I have a class that takes in a database url and username, connects to the database, and executes a query, assigning the results to a hash map.

import java.sql.*;
import java.util.Map;

public class MyClass {
    private final String dbUrl;
    private final String username;

    MyClass(final String dbUrl, final String username) {
        this.dbUrl = dbUrl;
        this.username = username;
    }

    public void queryDatabase(final Map<Integer, String> userIdToName) {
        final String query = "select user_id, name from users";

        try (final Connection connection = DriverManager.getConnection(dbUrl, username, null);
             final PreparedStatement ps = connection.prepareStatement(query);
             final ResultSet rs = ps.executeQuery()) {
            while (rs.next()) {
                final int userId = rs.getInt(1);
                final String name = rs.getString(2);
                userIdToName.put(userId, name);
            }
        } catch (final SQLException e) {
            System.out.println(e.toString());
        }
    }
}

我正在尝试使用 Mockito 来模拟queryDatabase() 我添加了 PowerMockito 来模拟DriverManager

我的测试 class:

import org.junit.Before;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.mock;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;

@RunWith(PowerMockRunner.class)
@PrepareForTest(DriverManager.class)
class MyClassTest {
    @Mock private Connection mockConnection = mock(Connection.class);
    @Mock private PreparedStatement mockStatement = mock(PreparedStatement.class);
    @Mock private ResultSet resultSet = mock(ResultSet.class);
    @InjectMocks private static MyClass myClass = new MyClass("test_url", "test_username");

    @Before
    public void setUp() throws Exception {
        mockStatic(DriverManager.class);
        when(DriverManager.getConnection(anyString(), anyString(), null)).thenReturn(mockConnection);
    }

    @Test
    void testQueryDatabase() throws Exception {
        when(mockConnection.prepareStatement(anyString())).thenReturn(mockStatement);
        when(mockStatement.executeQuery(anyString())).thenReturn(resultSet);
        when(resultSet.getInt(Mockito.anyInt())).thenReturn(1);
        when(resultSet.getString(anyInt())).thenReturn("john smith");

        final Map<Integer, String> useridToUser = new HashMap<>();
        myClass.queryDatabase(useridToUser);
        System.out.println(useridToUser);
    }
}

运行我的测试的 output 是:

java.sql.SQLException: No suitable driver found for test_url
{}

我预计:

{1=john smith}

我怎样才能正确地模拟这个?

除非绝对必要,否则我已阅读以避免使用PowerMock ,因此我也非常愿意接受重构建议,以尽可能避免使用。

您可以尝试执行以下操作:

class MyClassTest extends PowerMockTestCase {

添加依赖项:

    <dependency>
        <groupId>org.powermock.tests</groupId>
        <artifactId>powermock-tests-utils</artifactId>
        <version>1.6.6</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-testng</artifactId>
        <version>1.4.9</version>
        <scope>test</scope>
    </dependency>

也可能你需要 initMock 在设置:

@Before
public void setUp() throws Exception {
    mockStatic(DriverManager.class);
    initMocks(this);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM