在模拟方法中的静态PreparedStatement方法时测试CRUD操作

时间:2018-01-16 15:12:14

标签: java mysql junit mockito powermock

我的原始CRUD方法生成一个Prepared Statement并根据给定的参数设置字符串。

public class StatementUtility {
...
    public static PreparedStatement getFoo(String bar, Connection conn) {
        String query = "SELECT Foo FROM BarTable WHERE Bar = ?";

        PreparedStatement pstmt = null;
        try {
            pstmt = conn.prepareStatement(query);
            pstmt.setString(1, bar);
        }
        catch (SQLException e) {
            ..
        }
        return pstmt;
    }
...
}

在本声明中设置了我使用的数据库。我在我的MySQL服务器中创建了一个TestDB,我想测试一个删除方法:

public static String deleteFoo(List<String> input) {
    Connection conn = driver.connectCustomerDB(input);
    try(PreparedStatement pstmt = StatementUtility.getFoo(String someString, conn)) {
    ...
    }
}

到目前为止,这是我的测试

@RunWith(PowerMockRunner.class)
@PrepareForTest(StatementUtility.class)
public class DBConnectionBTBAdminTest {


    @Test
    public void deleteTest() {

        List<String> testInput = new ArrayList<>();
        testInput.add("hello");
        testInput.add("World");

        Driver driver = new Driver();
        Connection conn = driver.connectCustomerDB(testInput);

        String query = "FooBarFooBarFooBarFooBarFooBarFooBarFooBarFooBar";

        try {
            //try mocking the Method within
            BDDMockito.given(StatementUtility.getFoo(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), any(Connection.class))).willReturn(conn.prepareStatement(stringBuilder.toString()));
            //call the method I want to test
            SomeClass.deleteCategory(testInput, emptyArray);
            ...
        } catch (SQLException e) {
            ...
        }
    }
}

我得到的错误是方法中的Nullpointer Exception,我最初创建了PreparedStatement,但这不是重点,因为我根本不想进入这个方法,而是存根。

我也尝试使用Mockito而不是BDDMockito(请参阅此处:https://stackoverflow.com/a/21116014/8830232) 并使用实际值而不是ArgumentMatchers。*

我还尝试了一些其他的东西,比如嘲笑连接

目前我正在使用 JUnit@4.12 Mockito@2.13.0 powermock@1.7.1

  

编辑:   对于@glytching工作的答案,我不得不将mockito从2.x降级到1.x. &gt;在这种情况下不要忘记调整powermock依赖

1 个答案:

答案 0 :(得分:1)

@PrepareForTest(StatementUtility.class)(告诉PowerMock准备此类进行测试)之外,您还必须为StatementUtility的所有方法启用静态模拟。你这样做是通过调用...

PowerMockito.mockStatic(StatementUtility.class);

...在您尝试设置对该模拟的任何期望之前的测试中。

例如:

@RunWith(PowerMockRunner.class)
@PrepareForTest(StatementUtility.class)
public class DBConnectionBTBAdminTest {


    @Test
    public void deleteTest() {

        PowerMockito.mockStatic(StatementUtility.class);

        List<String> testInput = new ArrayList<>();
        testInput.add("hello");
        testInput.add("World");

        Driver driver = new Driver();
        Connection conn = driver.connectCustomerDB(testInput);

        String query = "FooBarFooBarFooBarFooBarFooBarFooBarFooBarFooBar";

        try {
           BDDMockito.given(StatementUtility.getFoo(...)).willReturn(...);

            ...
        } catch (SQLException e) {
            ...
        }
    }
}