测试(模拟)一个无效函数,它在内部调用其他与数据库建立连接的函数
Test(Mocking) a void function which internally calls other functions that create connection with database
我有一个class,其中有一个私有变量Connection。我想测试 functionA,为此我必须模拟 functionB 和 functionC。
我尝试使用 powermock 和 mockito 但无法做到。
测试 fucntionA 和模拟 functionB 和 functionC 应该做什么。
public class ToMock {
private Connection connection;
private static functionA(String name) {
// do something
functionB()
return xyz;
}
public static void functionB() {
connection = functionC("localhost", 10000);
}
public static void functionC(String hostName, int port) {
//make a connection to db
String connectionString = String.format("jdbc:hive2://%s:%d/",emrHost, port);
LOGGER.info("Connection string {}", connectionString);
try {
Class.forName("org.apache.hive.jdbc.HiveDriver");
Connection con = DriverManager.getConnection(connectionString, "hadoop", "");
LOGGER.info("Connected successfully");
return con;
} catch (ClassNotFoundException e) {
throw Throwables.propagate(e);
}
}
}
嗯,你有 static
方法。所以你不能按其设计使用 Mockito。你可以使用 PowerMock。
请参阅此处的用法:Link.
看这里:link.
基本上代码如下所示(从 PowerMock 示例复制),
@RunWith(PowerMockRunner.class)
@PrepareForTest(Static.class)
public class YourTestCase {
@Test
public void testMethodThatCallsStaticMethod() {
// mock all the static methods in a class called "Static"
PowerMockito.mockStatic(Static.class);
// use Mockito to set up your expectation
Mockito.when(Static.firstStaticMethod(param)).thenReturn(value);
Mockito.when(Static.secondStaticMethod()).thenReturn(123);
// execute your test
classCallStaticMethodObj.execute();
// Different from Mockito, always use PowerMockito.verifyStatic() first
// to start verifying behavior
PowerMockito.verifyStatic(Mockito.times(2));
// IMPORTANT: Call the static method you want to verify
Static.firstStaticMethod(param);
// IMPORTANT: You need to call verifyStatic() per method verification,
// so call verifyStatic() again
PowerMockito.verifyStatic(); // default times is once
// Again call the static method which is being verified
Static.secondStaticMethod();
// Again, remember to call verifyStatic()
PowerMockito.verifyStatic(Mockito.never());
// And again call the static method.
Static.thirdStaticMethod();
}
}
这里Static
是静态方法所属的class
像@neurotic-d 描述的那样重构你的代码。像这样:
public class ToMock {
private Connection connection;
public ToMock(Connection connection){
this.connection = connection;
}
private functionA(String name) {
// do something
return xyz;
}
}
public class ToMockFactory {
public static ToMock toMock(){
return new ToMock(functionB());
}
public static Connection functionB() {
return functionC("localhost", 10000);
}
public static Connection functionC(String hostName, int port) {
//make a connection to db
String connectionString = String.format("jdbc:hive2://%s:%d/",emrHost, port);
LOGGER.info("Connection string {}", connectionString);
try {
Class.forName("org.apache.hive.jdbc.HiveDriver");
Connection con = DriverManager.getConnection(connectionString, "hadoop", "");
LOGGER.info("Connected successfully");
return con;
} catch (ClassNotFoundException e) {
throw Throwables.propagate(e);
}
}
}
我有一个class,其中有一个私有变量Connection。我想测试 functionA,为此我必须模拟 functionB 和 functionC。
我尝试使用 powermock 和 mockito 但无法做到。
测试 fucntionA 和模拟 functionB 和 functionC 应该做什么。
public class ToMock {
private Connection connection;
private static functionA(String name) {
// do something
functionB()
return xyz;
}
public static void functionB() {
connection = functionC("localhost", 10000);
}
public static void functionC(String hostName, int port) {
//make a connection to db
String connectionString = String.format("jdbc:hive2://%s:%d/",emrHost, port);
LOGGER.info("Connection string {}", connectionString);
try {
Class.forName("org.apache.hive.jdbc.HiveDriver");
Connection con = DriverManager.getConnection(connectionString, "hadoop", "");
LOGGER.info("Connected successfully");
return con;
} catch (ClassNotFoundException e) {
throw Throwables.propagate(e);
}
}
}
嗯,你有 static
方法。所以你不能按其设计使用 Mockito。你可以使用 PowerMock。
请参阅此处的用法:Link.
看这里:link.
基本上代码如下所示(从 PowerMock 示例复制),
@RunWith(PowerMockRunner.class)
@PrepareForTest(Static.class)
public class YourTestCase {
@Test
public void testMethodThatCallsStaticMethod() {
// mock all the static methods in a class called "Static"
PowerMockito.mockStatic(Static.class);
// use Mockito to set up your expectation
Mockito.when(Static.firstStaticMethod(param)).thenReturn(value);
Mockito.when(Static.secondStaticMethod()).thenReturn(123);
// execute your test
classCallStaticMethodObj.execute();
// Different from Mockito, always use PowerMockito.verifyStatic() first
// to start verifying behavior
PowerMockito.verifyStatic(Mockito.times(2));
// IMPORTANT: Call the static method you want to verify
Static.firstStaticMethod(param);
// IMPORTANT: You need to call verifyStatic() per method verification,
// so call verifyStatic() again
PowerMockito.verifyStatic(); // default times is once
// Again call the static method which is being verified
Static.secondStaticMethod();
// Again, remember to call verifyStatic()
PowerMockito.verifyStatic(Mockito.never());
// And again call the static method.
Static.thirdStaticMethod();
}
}
这里Static
是静态方法所属的class
像@neurotic-d 描述的那样重构你的代码。像这样:
public class ToMock {
private Connection connection;
public ToMock(Connection connection){
this.connection = connection;
}
private functionA(String name) {
// do something
return xyz;
}
}
public class ToMockFactory {
public static ToMock toMock(){
return new ToMock(functionB());
}
public static Connection functionB() {
return functionC("localhost", 10000);
}
public static Connection functionC(String hostName, int port) {
//make a connection to db
String connectionString = String.format("jdbc:hive2://%s:%d/",emrHost, port);
LOGGER.info("Connection string {}", connectionString);
try {
Class.forName("org.apache.hive.jdbc.HiveDriver");
Connection con = DriverManager.getConnection(connectionString, "hadoop", "");
LOGGER.info("Connected successfully");
return con;
} catch (ClassNotFoundException e) {
throw Throwables.propagate(e);
}
}
}