你能帮我模拟一下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,但由于新的SimpleJdbcCall()以及.withSchemaName等,它被simpleJdbcCall覆盖了。我的预期是当调用新的SimpleJdbcCall返回mockedJdbcCall时,我设置了PowerMockito.whenNew...
我已经尝试了PowerMockito.whenNew的第1节和第2节,我是否误解了PowerMockito.whenNew?或者遗漏了代码中的任何东西?
请给我指引。
发布于 2021-01-28 04:52:12
您需要告诉PowerMock,您希望模拟HeartBeat类内部的SimpleJdbcCall类的构造。尝试向您的测试类添加以下注释:
@RunWith(PowerMockRunner.class)
@PrepareForTest(HeartBeat.class)
public class HeartBeatTest {
...
}https://stackoverflow.com/questions/65926898
复制相似问题