【问题标题】:Why does Alternator mock DynamoDB fail from maven but not Eclipse?为什么 Alternator 模拟 DynamoDB 从 maven 而不是 Eclipse 失败?
【发布时间】:2013-09-04 09:46:00
【问题描述】:

我已经就这个问题联系了Alternator的作者,他和我一样疑惑。简短的故事:我使用 Alternator 模拟框架编写了针对 DynamoDB 运行的代码的单元测试,当我从 Eclipse 中调用它们时工作正常,但从 maven 调用时失败。

故障源于 AWS 开发工具包本身:

com.amazonaws.AmazonServiceException: [java.lang.Error: property value is null.]
    at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:679) ~[aws-java-sdk-1.5.5.jar:na]
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:350) ~[aws-java-sdk-1.5.5.jar:na]
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:202) ~[aws-java-sdk-1.5.5.jar:na]
    at com.michelboudreau.alternatorv2.AlternatorDBClientV2.invoke(AlternatorDBClientV2.java:225) ~[alternator-0.6.4.jar:na]
    at com.michelboudreau.alternatorv2.AlternatorDBClientV2.updateItem(AlternatorDBClientV2.java:99) ~[alternator-0.6.4.jar:na]
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$2.executeLowLevelRequest(DynamoDBMapper.java:646) ~[aws-java-sdk-1.5.5.jar:na]
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$SaveObjectHandler.execute(DynamoDBMapper.java:767) ~[aws-java-sdk-1.5.5.jar:na]
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.save(DynamoDBMapper.java:658) ~[aws-java-sdk-1.5.5.jar:na]
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.save(DynamoDBMapper.java:488) ~[aws-java-sdk-1.5.5.jar:na]
    at com.somoglobal.eventdata.Controller.addDeviceKeys(Controller.java:531) ~[classes/:na]

正如您所见,这并不是非常有用,因为堆栈跟踪本身只是在 AWS 开发工具包从通过(模拟)远程接收到的响应中组装异常时显示堆栈服务。

相关版本号:

  • Maven 3.0.4
  • Java 1.7.0_10
  • AWS SDK 1.5.5(虽然我也尝试过 1.5.3 和 1.5.4)
  • Eclipse 版本“Kepler”,内部版本号:20130614-0229

再深入一点,项目的(略微省略的)pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <parent>
        <groupId>snip</groupId>
        <artifactId>snip</artifactId>
        <version>1.14.2-SNAPSHOT</version>
    </parent>
    <artifactId>snip</artifactId>
    <version>1.6.0-SNAPSHOT</version>
    <name>snip</name>
    <dependencies>
        ...snip...
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk</artifactId>
            <version>1.5.5</version>
        </dependency>
        <dependency>
            <groupId>com.michelboudreau</groupId>
            <artifactId>alternator</artifactId>
            <version>0.6.4</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

以及略微缩减的测试:

package com.xxx;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.joda.time.DateTime;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;

import com.amazonaws.Request;
import com.amazonaws.handlers.RequestHandler;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.CreateTableResult;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughputExceededException;
import com.amazonaws.util.TimingInfo;
import com.michelboudreau.alternator.AlternatorDB;
import com.michelboudreau.alternatorv2.AlternatorDBClientV2;
import com.xxx.stuff;

public class ControllerTest {

    private static Controller instance;   
    private static DynamoDBMapper mapper;
    private static AlternatorDB db;
    private static AlternatorDBClientV2 client;

    @BeforeClass
    public static void setup() throws Exception {
        client = new AlternatorDBClientV2();
        mapper = new DynamoDBMapper(client);
        db = new AlternatorDB().start();
        // code to create dynamodb was here
        instance = new Controller(mapper);
    }

    @AfterClass
    public static void tearDown() throws Exception {
        db.stop();
    }

    @Test
    public void testAddDeviceKeys() {
        Collection<DeviceKey> keys = EventDataModelMapper.getDeviceKeys(ClassFixtures.event);
        assertNotNull("keys should not be null", keys);
        assertFalse("keys should not be empty", keys.isEmpty());

        boolean result = instance.addDeviceKeys(keys);
        assertTrue("result should be true", result);
    }
}

被测代码可能并没有特别涉及此故障 - 我已经进行了足够的调试跟踪以查看它在直接通过 Eclipse 调用和从 maven 运行时在测试期间的行为相同。

编辑

实际上,Alternator 可能与此有关,因为有问题的错误消息可能来自 com.michelboudreau.alternator.validation.ValidatorUtils:

    public static <T> List<Error> rejectIfNull(T property) {
            List<Error> errors = new ArrayList<Error>();
            if (property == null) {
                    errors.add(new Error("property value is null."));
            }
            return errors;
    }

【问题讨论】:

  • 未来需要注意的一点:很多时候,由于 Maven Surefire 插件运行的测试顺序与您的 IDE 运行的测试顺序不同,可能会出现这样的差异。这通常是由修改某种状态的测试引起的,这种状态会延续到后续测试中。

标签: java amazon-web-services amazon-dynamodb alternator


【解决方案1】:

好的,停下来,交流发电机没有错,问题最终出在我工作场所的一把椅子和键盘之间。有问题的错误消息确实是由 Alternator 引起的,最终源于缺少表定义 - 由于非常复杂的原因,当通过 Maven 运行测试时,通过 Alternator 创建的模拟 Dynamodb 表的名称与被测代码试图访问的表名。

我要公开感谢 Michel Boudreau 在我就此事直接与他联系时抽出时间作出回应。

【讨论】:

  • 就是我!真高兴你做到了。你应该尽可能接受你的答案。
【解决方案2】:

相反,您可以在本地运行 Amazon DynamoDB。

http://aws.typepad.com/aws/2013/09/dynamodb-local-for-desktop-development.html

【讨论】:

    【解决方案3】:

    相反,您可以使用 jcabi-dynamodb-maven-plugin(我是开发人员)运行 DynamoDB Local。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 1970-01-01
      相关资源
      最近更新 更多