我在使用MockitoJUnitRunner模拟JDBC调用时遇到问题。
即使我在测试类中有下面的内容,Mockito也不知如何模拟了实际的调用。

when(readOnlyJdbcTemplate.query(anyString(), any(Object[].class), any(int[].class), any(FeatureCollectionResponseExtractor.class))).thenReturn(actual);


非常相似的模拟在另一个类中适用于非常相似的方法类型。它们之间的唯一区别是我的其他类确实具有3个参数而不是4个参数。下面是针对不同类成功模拟的代码。

when(readOnlyJdbcTemplate.query(anyString(), any(Object[].class), any(FeaturesResultExtractor.class))).thenReturn(actual);


下面是我的实际代码。

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.inject.Inject;
import javax.inject.Named;
import java.net.HttpURLConnection;
import java.sql.Types;

import static com.accounts.features.utils.Constants.INTERNAL_SERVER_ERROR;

@Profile
@Log
@Named("featureLibraryDao")
public class FeatureLibraryDaoImpl implements FeatureLibraryDao {

    private static final Logger LOGGER = LogManager.getLogger(FeatureLibraryDaoImpl.class);

    @Value("${feature.library.function.sql.query}")
    private String sqlSelectQuery;

    @Inject
    @Named("readOnlyJdbcTemplate")
    private JdbcTemplate readOnlyJdbcTemplate;

    @Override
    public FeatureCollectionDTO getFeaturesData(FeatureRequest request) {
        try {
            int[] argTypes = new int[] { Types.BIGINT, Types.VARCHAR, Types.SMALLINT};
            return readOnlyJdbcTemplate.query(sqlSelectQuery, new Object[] {
                        Long.parseLong(request.getAccountId()), request.getRequestedFeatures(), request.getApplicationSuffix()
                    }, argTypes,
                    new FeatureCollectionResponseExtractor(request));
        } catch (CustomException cbe) {
            throw cbe;
        } catch (Exception ex) {
            LOGGER.error("getFeaturesData method failed with error message:{}", ex.getMessage(), ex);

            CustomErrorCode error = new CustomErrorCode(INTERNAL_SERVER_ERROR);
            error.setDeveloperText(ex.getMessage());
            throw new CustomSystemException(error, HttpURLConnection.HTTP_INTERNAL_ERROR);
        }
    }

}


下面是我的测试课。

@RunWith(MockitoJUnitRunner.class)
public class FeatureLibraryDaoImplTest {

    @InjectMocks
    private FeatureLibraryDaoImpl dao;

    @Mock
    private JdbcTemplate readOnlyJdbcTemplate;

    private List<String> features = Arrays.asList("excl_clsd_ind_only", "excl_chrgoff_ind_only", "excl_dsput_ind_only");

    @Test
    public void getFeaturesDataWhenSuccess() {
        //given
        FeatureRequest request = getFeatureRequest();
        FeatureCollectionDTO actual = new FeatureCollectionDTO(features);

        when(readOnlyJdbcTemplate.query(anyString(), any(Object[].class), any(int[].class), any(FeatureCollectionResponseExtractor.class))).thenReturn(actual);

        //when
        FeatureCollectionDTO dto = dao.getFeaturesData(request);

        //then
        assertThat(dto, notNullValue());
    }
}


关于这里有什么问题的任何建议吗? any(int[].class)有什么问题吗?

最佳答案

我确实看到您在测试用例中没有传递sql查询sqlSelectQuery值,但是在模拟过程中您指定了anyString(),因此它必须是某个值,但不能为null。由于您正在使用spring项目,因此可以使用ReflectionTestUtils设置对象的字段值

@Before
public void setUp() {
    ReflectionTestUtils.setField(dao, "sqlSelectQuery", "query");

}

08-06 03:51