- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的问题类似于this SO question
我在服务中有两个 JdbcTemplate.queryForObject(..,...,...,)
调用,如下所示,
depositPostedAmt = jdbcTemplate.queryForObject(Constants.FETCH_DEPOSIT_POSTED_AMT, BigDecimal.class,new Object[] { remitBean.getDepositId() });
和
claimPostedAmt =jdbcTemplate.queryForObject(Constants.FETCH_CLAIM_POSTED_AMOUNT,BigDecimal.class, new Object[] { claim.getClaimId(), remitBean.getContractNum() });
第三个参数,new Object[]
在这两个调用中是不同的,并且实际的 sql 字符串也不同。因此,我尝试使用不同的模拟在两种情况下返回两个不同的对象,如下所示,
when(jdbcTemplate.queryForObject(eq(Constants.FETCH_DEPOSIT_POSTED_AMT), eq(BigDecimal.class), anyObject())).thenReturn(depositPostedAmt);
when(jdbcTemplate.queryForObject(eq(Constants.FETCH_CLAIM_POSTED_AMOUNT), eq(BigDecimal.class), anyObject())).thenReturn(claimPostedAmt);
即我希望在两个不同的查询上收到两个不同的 BigDecimal
。
我按预期收到了 depositPostedAmt
但 claimPostedAmt
始终为 null,即使我已经在 @Before 方法中将其初始化,与 depositPostedAmt
相同,所以我猜测我的 when
匹配器没有找到任何匹配项。我已经尝试了第三个参数匹配的各种语法,例如 any(Object[].class)
和 anyRef(objectArray)
等,但第二次,我总是得到 NULL。
我不确定我错过了什么,因为没有错误。我正在使用 JUnit 和 Mockito 1.9.5。
这里是示例代码 - 一切正常,除了 claimPostedAmt
在被调用的服务中保持为空。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class, loader = AnnotationConfigContextLoader.class)
public class RCMatchDaoImplTest{
@Autowired private RCMatchDaoImpl service;
@Autowired private JdbcTemplate jdbcTemplate;
@Autowired private Logger logger;
private RemitBean remitBean;
private List<RemitBean> remitBeanList;
private BigDecimal depositPostedAmt,claimPostedAmt,remitAmount;
private ClaimVO claim;
private List<ClaimVO> claims;
@Before
public void setUp() throws NoSuchFieldException, SecurityException, Exception{
/* Set dependencies*/
service.setJdbcTemplate(jdbcTemplate);
setFinalStatic(RCMatchDaoImpl.class.getDeclaredField("logger"),logger);
remitBean = new RemitBean();
remitBeanList=new ArrayList<>();
claim= new ClaimVO();
claims= new ArrayList<>();
remitBeanList.add(remitBean);
depositPostedAmt=new BigDecimal(-10);
claimPostedAmt = new BigDecimal(-10);
remitAmount=new BigDecimal(20);
claims.add(claim);
}
private static void setFinalStatic(Field field, Object newValue) throws Exception{
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
@Test
public void testLucenePost_refund_success() throws SQLException{
/* Set Data */
remitBean.setRemitType("R");
remitBean.setRemitAmt(remitAmount);
remitBean.setDepositId(6866418);
remitBean.setClaims(claims);
depositPostedAmt=depositPostedAmt.add(new BigDecimal(20));
claimPostedAmt=claimPostedAmt.add(new BigDecimal(10));
claim.setClaimId(6866418);
claim.setContractNum("100");
Object[] depositParams = new Object[] { 6866418 };
Object[] claimParams = new Object[] { 6866418,"100" };
/* Record Invocations*/
when(jdbcTemplate.queryForObject(eq(Constants.FETCH_DEPOSIT_POSTED_AMT), eq(BigDecimal.class), anyObject())).thenReturn(depositPostedAmt);
when(jdbcTemplate.queryForObject(eq(Constants.FETCH_CLAIM_POSTED_AMOUNT), eq(BigDecimal.class), anyObject())).thenReturn(claimPostedAmt);
doNothing().when(logger).error(anyString());
/* Play the Service */
service.lucenePost(remitBeanList);
/* Verify Results */
/* reset data to original value as in SetUp method*/
}
为了完整起见,这也是我的上下文类,
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.slf4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
@Configuration
public class TestConfig {
@Mock JdbcTemplate jdbcTemplate;
@Mock Logger logger;
TestConfig(){
MockitoAnnotations.initMocks(this);
}
@Bean
public RCMatchDaoImpl getRCMatchDaoImpl() {
return new RCMatchDaoImpl();
}
@Bean
public JdbcTemplate jdbcTemplate(){
return jdbcTemplate;
}
@Bean
public Logger logger(){
return logger;
}
}
最佳答案
我确实使用了这个(使用 Mockito 1.10.19):
when(jdbcTemplate.queryForObject(eq(Constants.FETCH_DEPOSIT_POSTED_AMT), eq(BigDecimal.class), anyVararg())).thenReturn(depositPostedAmt);
when(jdbcTemplate.queryForObject(eq(Constants.FETCH_CLAIM_POSTED_AMOUNT), eq(BigDecimal.class), anyVararg())).thenReturn(claimPostedAmt);
这正在按预期工作。输出:
10
0
正如预期的那样。
一些阅读:http://site.mockito.org/mockito/docs/current/org/mockito/ArgumentMatchers.html#anyVararg()
<小时/>使用的代码:
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = RCMatchDaoImplTest.TestConfig.class, loader = AnnotationConfigContextLoader.class)
public class RCMatchDaoImplTest {
@Autowired
private RCMatchDaoImpl service;
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private Logger logger;
private RemitBean remitBean;
private List<RemitBean> remitBeanList;
private BigDecimal depositPostedAmt, claimPostedAmt, remitAmount;
private ClaimVO claim;
private List<ClaimVO> claims;
@Before
public void setUp() throws NoSuchFieldException, SecurityException, Exception {
/* Set dependencies*/
service.setJdbcTemplate(jdbcTemplate);
setFinalStatic(RCMatchDaoImpl.class.getDeclaredField("logger"), logger);
remitBean = new RemitBean();
remitBeanList = new ArrayList<>();
claim = new ClaimVO();
claims = new ArrayList<>();
remitBeanList.add(remitBean);
depositPostedAmt = new BigDecimal(-10);
claimPostedAmt = new BigDecimal(-10);
remitAmount = new BigDecimal(20);
claims.add(claim);
}
private static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
@Test
public void testLucenePost_refund_success() throws SQLException {
/* Set Data */
remitBean.setRemitType("R");
remitBean.setRemitAmt(remitAmount);
remitBean.setDepositId(6866418);
remitBean.setClaims(claims);
depositPostedAmt = depositPostedAmt.add(new BigDecimal(20));
claimPostedAmt = claimPostedAmt.add(new BigDecimal(10));
claim.setClaimId(6866418);
claim.setContractNum("100");
Object[] depositParams = new Object[]{6866418};
Object[] claimParams = new Object[]{6866418, "100"};
/* Record Invocations*/
when(jdbcTemplate.queryForObject(eq(Constants.FETCH_DEPOSIT_POSTED_AMT), eq(BigDecimal.class), anyVararg())).thenReturn(depositPostedAmt);
when(jdbcTemplate.queryForObject(eq(Constants.FETCH_CLAIM_POSTED_AMOUNT), eq(BigDecimal.class), anyVararg())).thenReturn(claimPostedAmt);
doNothing().when(logger).error(anyString());
/* Play the Service */
service.lucenePost(remitBeanList);
/* Verify Results */
/* reset data to original value as in SetUp method*/
}
@Configuration
public static class TestConfig {
@Mock
JdbcTemplate jdbcTemplate;
@Mock
Logger logger;
TestConfig() {
MockitoAnnotations.initMocks(this);
}
@Bean
public RCMatchDaoImpl getRCMatchDaoImpl() {
return new RCMatchDaoImpl();
}
@Bean
public JdbcTemplate jdbcTemplate() {
return jdbcTemplate;
}
@Bean
public Logger logger() {
return logger;
}
}
public static class RCMatchDaoImpl {
public static final Logger logger = LoggerFactory.getLogger(RCMatchDaoImpl.class);
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(final JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void lucenePost(final List<RemitBean> remitBeanList) {
for (RemitBean remitBean : remitBeanList) {
System.out.println(jdbcTemplate.queryForObject(Constants.FETCH_DEPOSIT_POSTED_AMT, BigDecimal.class, new Object[]{remitBean.getDepositId()}));
for (ClaimVO claimVO : remitBean.getClaims()) {
System.out.println(jdbcTemplate.queryForObject(Constants.FETCH_CLAIM_POSTED_AMOUNT, BigDecimal.class, new Object[]{claimVO.getClaimId(), remitBean.getContractNum()}));
}
}
}
}
public static class RemitBean {
private String remitType;
private BigDecimal remitAmt;
private int depositId;
private List<ClaimVO> claims;
private Object contractNum;
public void setRemitType(final String remitType) {
this.remitType = remitType;
}
public void setRemitAmt(final BigDecimal remitAmt) {
this.remitAmt = remitAmt;
}
public void setDepositId(final int depositId) {
this.depositId = depositId;
}
public int getDepositId() {
return depositId;
}
public void setClaims(final List<ClaimVO> claims) {
this.claims = claims;
}
public List<ClaimVO> getClaims() {
return claims;
}
public Object getContractNum() {
return contractNum;
}
}
public static class ClaimVO {
private int claimId;
private String contractNum;
public void setClaimId(final int claimId) {
this.claimId = claimId;
}
public int getClaimId() {
return claimId;
}
public void setContractNum(final String contractNum) {
this.contractNum = contractNum;
}
}
static class Constants {
public static final String FETCH_DEPOSIT_POSTED_AMT = "1";
public static final String FETCH_CLAIM_POSTED_AMOUNT = "2";
}
}
关于java - 使用 Mockito 1.9.5 模拟 JdbcTemplate.queryForObject(..,...,...,),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40257093/
我发现这种形式的查询对于从数据库调用返回单个值/单行非常方便,并且如果出现问题,我可以接受它抛出异常。但我认为进行类型转换通常是一种不好的做法。 这里的 Actor 是否会被人皱眉? String n
我正在尝试使用jdbcTemplate.queryForObject将普通查询更改为参数化查询,以避免SQL注入(inject)。但查询返回 EmptyResultDataAccessExceptio
我有这个 SQL 语句: return jdbcTemplate.queryForObject("SELECT * FROM materials WHERE title = ?", new Mater
我的方法是这样的: public class Decompile extends JdbcDaoSupport public void getRunner(){ String val = this.g
我正在使用 JdbcTemplate.queryForObject(String sql, RowMapper rowMapper, Object...args) 从 Oracle 获取一行,但不断收
我想做的是使用queryForObject从studentstable中选择用户名、密码和角色。 在我的 JdbcTemplate 语法中是 public static Object queryFor
String lastName = this.jdbcTemplate.queryForObject("select last_name from t_actor where id = ?", new
我想知道如何在我的案例中正确使用 jdbc。 saveLinkHistory 列在 mysql 中是一个 bit(1) 类型。 public boolean getIsSavedLinkHistory
我想创建一个通用方法,应该如下所示: public getCell(S column,R arg){ return jdbcTemplate.queryForObject("select ? fro
将 Kotlin 和 Spring 5 用于一些简单的项目。 我想使用 queryForObject 通过 id 从数据库中获取单条记录. 我的查询是“按 id 进行简单选择”: jdbc.query
Java 1.7/Spring 3.1 看看下面的代码。 BigDecimal value = queryAsObject (BigDecimal.class, "select balance
我的问题类似于this SO question 我在服务中有两个 JdbcTemplate.queryForObject(..,...,...,) 调用,如下所示, depositPostedAmt
我正在尝试使用 jdbctemplate.queryForObject(query,Object[]{},Integer.class) 方法获取行数,我在 mysql.properties 文件中定义
无法确定导致此异常的主要原因在哪里。我按照 Spring in Action 的书做了一切。这几行代码有什么问题? private static final String PREFIX_SELECT_
我在 DAO 中创建了一个方法: public String getUserName(int userid){ String sql="SELECT userName from UserDet
我是一名优秀的程序员,十分优秀!