2016-10-26 91 views
0

我的問題是類似this SO question嘲諷JdbcTemplate.queryForObject(...,...,...)與1.9.5的Mockito

我有類似下面服務中有兩個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總是空,即使我在@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; 
    } 
} 
+0

我們可以看到整個測試(也許你可以張貼一些[MCVE])? –

+0

@AdrianShum - 不,在實際的方法調用中,它不是「BigDecimal」的Object實例,而是「.class」參數。 –

+0

雅,發現立即評論並立即刪除評論:P –

回答

1

我也用這個(與19年1月10日的Mockito):

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"; 
    } 
} 
+0

我在1.9.5上,'anyVararg()'給了我這個錯誤,'參數是不同的!通緝: jdbcTemplate.queryForObject( 「Query」, class java.math.BigDecimal, ); - > at com.hmsy.bp.dao.RCMatchDaoImplTest.testLucenePost_refund_success(RCMatchDaoImplTest。的java:110) 實際調用具有不同的參數: jdbcTemplate.queryForObject( 「查詢」, 類java.math.BigDecimal, 6866418, 空 );' –

+0

所以額外的參數 - 'remitBean.getContractNum()'導致失敗。如果我在服務代碼中刪除'remitBean.getContractNum()',它就可以工作。那麼'anyObject()'也可以。數組中的兩個對象造成了不同。 –

+0

「給我這個錯誤,參數是不同的!」來自一些'verify()'! –