Не удается запустить тест Junit для класса dynamodb

#java #amazon-web-services #amazon-dynamodb #aws-sdk

Вопрос:

У меня есть класс, который сканирует столбец из таблицы базы данных dynamo, используя при этом aws sdk для java(основной метод, взятый для простоты):

 public class fetchCmdbColumn {
    
    public static List<String> CMDB(String tableName, String tableColumn) throws Exception {

        DynamoDbClient client = DynamoDbClient.builder()
                .region(Region.EU_WEST_1)
                .build();
        List<String> ListValues = new ArrayList<>();
        
        try {
            
            ScanRequest scanRequest = ScanRequest.builder()
                        .tableName(tableName)
                        .build();
            ScanResponse response = client.scan(scanRequest);

            for (Map<String, AttributeValue> item : response.items()){
                Set<String> keys = item.keySet();
                for (String key : keys) {
                    
                    if (key == tableColumn) {
                        ListValues.add(item.get(key).s()) ;
                    }
                }
            }
            //To check what is being returned, comment out below
           // System.out.println(ListValues);
            
        } catch (DynamoDbException e){
            e.printStackTrace();
            System.exit(1);
        }
        client.close();
        return ListValues;
        
    }
}
 

У меня также есть тесты junit, созданные для этого класса:

 public class fetchCMDBTest {


    // Define the data members required for the test
    private static String tableName = "";
    private static String tableColumn = "";


    @BeforeAll
    public static void setUp() throws IOException {

        // Run tests on Real AWS Resources
        try (InputStream input = fetchCMDBTest.class.getClassLoader().getResourceAsStream("config.properties")) {

            Properties prop = new Properties();

            if (input == null) {
                System.out.println("Sorry, unable to find config.properties");
                return;
            }

            //load a properties file from class path, inside static method
            prop.load(input);

            // Populate the data members required for all tests
            tableName = prop.getProperty("environment_list");
            tableColumn = prop.getProperty("env_name");


        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @Test
    void fetchCMDBtable() throws Exception{
        try {
            fetchCMDB.CMDB(tableName, tableColumn);
            System.out.println("Test 1 passed");
        } catch (Exception e) {
            System.out.println("Test 1 failed!");
            e.printStackTrace();
        }
        
    }   
}
 

Когда я запускаю тест с помощью mvn-теста, я получаю ошибку:

software.amazon.awssdk.core.exception.SdkClientException: Multiple HTTP implementations were found on the classpath ,

даже несмотря на то, что я только один раз объявил построителя клиентов в классе.

Что я упускаю?

Комментарии:

1. Почему вы пытаетесь выполнить модульные тесты для реальной базы данных? Я не думаю, что вам нужно это делать, если только вам не нужно провести какое-то интеграционное тестирование. Если последнее не является вашей целью, то просто издевайтесь над клиентом базы данных и тестируйте свой код с помощью насмешек.

Ответ №1:

Я запускаю модульные тесты из среды разработки IntelliJ. Я нахожу, что использование IDE работает лучше, чем из командной строки. Как только я настрою файл config.properties, содержащий значения для тестов, и запущу их, все тесты пройдут, как показано здесь:

введите описание изображения здесь

На самом деле — мы тестируем все примеры кода Java V2 таким образом, чтобы убедиться, что все они работают.

Я также протестировал все примеры DynamoDB из командной строки с помощью теста mvn . Все прошло:

введите описание изображения здесь

Измените свой тест, чтобы создать один экземпляр клиента DynamoDB, а затем в качестве первого теста убедитесь, что он был успешно создан. Посмотрим, сработает ли это для вас. Как только у вас это заработает, добавьте дополнительные тесты!

 public class DynamoDBTest {

    private static DynamoDbClient ddb;

   

    @BeforeAll
    public static void setUp() throws IOException {

        // Run tests on Real AWS Resources
        Region region = Region.US_WEST_2;
        ddb = DynamoDbClient.builder().region(region).build();
        try (InputStream input = DynamoDBTest.class.getClassLoader().getResourceAsStream("config.properties")) {

            Properties prop = new Properties();

            if (input == null) {
                System.out.println("Sorry, unable to find config.properties");
                return;
            }

            //load a properties file from class path, inside static method
            prop.load(input);

           

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @Test
    @Order(1)
    public void whenInitializingAWSService_thenNotNull() {
        assertNotNull(ddb);
        System.out.println("Test 1 passed");
    }
 

Комментарии:

1. я вроде как должен использовать vscode для этого

2. Я также обновлю свой ответ, чтобы показать использование командной строки. Я использую тест mvn, и все тесты пройдены. Смотрите снимок экрана.

3. Если у вас все еще есть проблемы — свяжитесь со мной по ссылке (см. Профиль), и я помогу вам запустить их.

Ответ №2:

Оказывается, в моем файле pom содержались другие клиенты, поэтому пришлось удалить подобные :

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>netty-nio-client</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>apache-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
 

и заменил их на :

     <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>aws-crt-client</artifactId>
        <version>2.14.13-PREVIEW</version>
    </dependency>
 

как упоминалось в https://aws.amazon.com/blogs/developer/introducing-aws-common-runtime-http-client-in-the-aws-sdk-for-java-2-x/

Ответ №3:

в качестве дополнения к другим ответам, для меня работал только вариант 4 из ссылки.

Вариант 4. Измените HTTP-клиент по умолчанию, используя системное свойство в коде Java.

Я определил его по setUp() методу моего интеграционного теста с использованием JUnit 5.

 @BeforeAll
public static void setUp() {
    System.setProperty(
         SdkSystemSetting.SYNC_HTTP_SERVICE_IMPL.property(), 
         "software.amazon.awssdk.http.apache.ApacheSdkHttpService");
}
 

и потому, что я использую gradle:

     implementation ("software.amazon.awssdk:s3:${awssdk2Version}") {
        exclude group: 'software.amazon.awssdk', module: 'netty-nio-client'
        exclude group: 'software.amazon.awssdk', module: 'apache-client'
    }
    implementation "software.amazon.awssdk:aws-crt-client:2.17.71-PREVIEW"