2016-10-26 7 views
0

Мой вопрос похож на this SO questionMocking JdbcTemplate.queryForObject (.., ..., ...,) с Mockito 1.9.5

У меня есть два 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', а аргумент' .class'. –

+0

ya, нашел, что сразу после комментирования и сразу же удалил комментарий: P –

ответ

1

Я действительно использовал это (с 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"; 
    } 
} 
+0

Я на 1.9.5, и 'anyVararg()' дает мне эту ошибку, 'Аргумент (ы) разные! Требуется: jdbcTemplate.queryForObject ( "Query", класс 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()'! –

Смежные вопросы