java - 如何模拟新的 SimpleJdbcCall
问题描述
你能帮我模拟 SimpleJdbcCall 吗?
要测试的实际课程如下。
import java.sql.Types;
import java.util.HashMap;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class HeartBeat {
private static final Logger LOGGER = LogManager.getLogger(HeartBeat.class);
@Autowired
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
private SimpleJdbcCall jdbcCall;
@PostConstruct
private void applicationStarted() {
LOGGER.info("Application has Started.");
DBCall();
}
@Scheduled(fixedRateString="${application.heartbeatInterval}")
public void sendHeartbeat() {
DBCall();
}
private void DBCall() {
if ( this.jdbcTemplate == null ) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
jdbcTemplate.setResultsMapCaseInsensitive(true);
jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withSchemaName("schema")
.withCatalogName("catalogName")
.withProcedureName("cleanup");
jdbcCall.execute(new HashMap<String, Object>(0));
jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withSchemaName("schema")
.withCatalogName("catalogName")
.withProcedureName("register")
.declareParameters(new SqlParameter("id", Types.VARCHAR))
.declareParameters(new SqlParameter("name", Types.VARCHAR));
MapSqlParameterSource paramMap = new MapSqlParameterSource().addValue("id", "abc").addValue("name", "def");
jdbcCall.execute(paramMap);
}
}
为了测试上面的代码,我创建了
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyMap;
import java.util.HashMap;
import java.util.Map;
public class HeartBeatTest {
HeartBeat heartBeat;
private JdbcTemplate mockedJdbcTemplate;
private SimpleJdbcCall mockedJdbcCall;
private Map<String, Object> result;
@Before
public void setUp() throws Exception {
this.heartBeatComponent = new HeartBeatComponent();
result = new HashMap<String, Object>();
mockedJdbcTemplate = Mockito.mock(JdbcTemplate.class);
mockedJdbcCall = Mockito.mock(SimpleJdbcCall.class);
Whitebox.setInternalState(heartBeatComponent, "jdbcTemplate",mockedJdbcTemplate);
Whitebox.setInternalState(heartBeatComponent, "jdbcCall",mockedJdbcCall);
// section1
//PowerMockito.whenNew(SimpleJdbcCall.class).withArguments(mockedJdbcTemplate).thenReturn(mockedJdbcCall);
// section2
PowerMockito.whenNew(SimpleJdbcCall.class).withAnyArguments().thenReturn(mockedJdbcCall);
Mockito.when(mockedJdbcCall.withSchemaName(any(String.class))).thenReturn(mockedJdbcCall);
Mockito.when(mockedJdbcCall.withCatalogName(any(String.class))).thenReturn(mockedJdbcCall);
Mockito.when(mockedJdbcCall.withProcedureName(any(String.class))).thenReturn(mockedJdbcCall);
}
@Test
public void sendHeartbeatTest() {
Mockito.when(mockedJdbcCall.execute(anyMap())).thenReturn(result);
Mockito.when(mockedJdbcCall.execute(any(MapSqlParameterSource.class))).thenReturn(result);
heartBeat.sendHeartbeat();
Mockito.verify(mockedJdbcCall, Mockito.times(1)).execute(anyMap());
Mockito.verify(mockedJdbcCall, Mockito.times(1)).execute(any(MapSqlParameterSource.class));
}
}
但它没有按预期工作。我从调试模式中可以看到,jdbcCall 得到了 mockedJdbcCall,但是由于 new SimpleJdbcCall() 以及 .withSchemaName 等,它被 simpleJdbcCall 覆盖。我的期望是当新的 SimpleJdbcCall 被调用时,它返回 mockedJdbcCall 我设置了 PowerMockito.whenNew...
我已经为 PowerMockito.whenNew 尝试了第 1 节和第 2 节 我误解了 PowerMockito.whenNew 吗?还是错过了代码中的任何内容?
请指导我。
解决方案
你需要告诉 PowerMock 你想在SimpleJdbcCall
类中模拟类的构造HeartBeat
。尝试将以下注释添加到您的测试类:
@RunWith(PowerMockRunner.class)
@PrepareForTest(HeartBeat.class)
public class HeartBeatTest {
...
}
推荐阅读
- javascript - 如何添加不与更新内容功能冲突的自动图像幻灯片放映
- python - pd.DataFrame 上的 for 循环继续运行,但在 100 次迭代后停止工作
- php - 如何插入或更新来自不同表的记录
- arrays - C char 数组在赋值循环后丢失指针
- azure-data-factory - Azure 数据工厂 - 不安然后删除
- c# - 如何在 C# 中使用 sendgrid 添加回复
- python - 我喜欢从双重列表中消除重复的组件,然后合并双重列表
- java - 没有 res 文件夹。没有activity_main.xml。没有活动。无布局
- azure-devops - Devops 构建管道未将测试文件复制到 bin 文件夹
- python - 使用 datetime 获取上个月的日期