Проблема с заглушкой / издевательством над методом делает вызов БД - PullRequest
2 голосов
/ 17 октября 2019

У меня проблема с Mocking при вызове JDBC с использованием MockitoJUnitRunner. Каким-то образом 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)?

Ответы [ 2 ]

1 голос
/ 17 октября 2019

Я вижу, что вы не передаете значение sql запроса sqlSelectQuery во время теста, но во время имитации вы указали anyString(), поэтому оно должно быть некоторым значением, но не нулевым. Поскольку вы используете spring проект, вы можете использовать ReflectionTestUtils, чтобы установить значение поля для объекта

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

}
0 голосов
/ 18 октября 2019

Эй, ребята, большое спасибо за все ваши предложения. Итак, я обнаружил, что тестовый код в порядке. В некоторых случаях тег @Value не вставлял фактическое значение sqlSelectQuery в основной файл кода. @Value("${feature.library.function.sql.query}") private String sqlSelectQuery;

Вместо этого я изменил код на private String sqlSelectQuery = "${feature.library.function.sql.query}", и все тесты проходят успешно.

Почему-то sqlSelectQuery не получало значение, и, следовательно, Mockito не издевался надфактический вызов метода. Я все еще рассматриваю, почему @value не работает так, как должно быть.

...