大前端

前端学习之家-大前端

6. AWS DynamoDB实战之本地单元测试

Overview

  • 对数据持久层进行测试时,需要连接数据库.一个好的DAO测试应该保证数据库在测试前后状态一致,不留新添数据,回滚所有更新.为了防止测试数据污染数据库,实际开发过程中一般是不允许直接对实际数据库进行写操作的.
  • 这种情况使用内存数据库是个不错选择。每次测试前都能保证数据库是空空的,没有任何表,并且测试完成后不留痕迹.
  • aws提供了dynamodb local来作为测试用的内存数据库

单元测试DAO

配置mvn setting

mvn setting位于~/.m2/setting.xml, 配置文件如下,对dynamodb-local以外的其他资源都使用阿里云镜像进行下载.

<profile>
  <id>jdk-1.8</id>
  <activation>
    <activeByDefault>true</activeByDefault>
    <jdk>1.8</jdk>
  </activation>
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
    <downloadSources>true</downloadSources>
    <downloadJavadocs>true</downloadJavadocs>
  </properties>
  <mirrors>
    <mirror>
        <id>aliyunmaven</id>
        <mirrorOf>*,!dynamodb-local</mirrorOf>
        <name>alirepo</name>
        <url>https://maven.aliyun.com/repository/public</url>
    </mirror>
  </mirrors>
</profile>

配置pom

整个pom文件配置如下,相比之前,增加了以下内容:

  • 添加DynamoDBLocal的依赖
  • 配置DynamoDBLocal的repository
  • 使用plugin配置 in memory database的路径
<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">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.jessica</groupId>
  <artifactId>dynamodb-in-action</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>dynamodb-in-action</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
	<maven.compiler.source>1.8</maven.compiler.source>
	<maven.compiler.target>1.8</maven.compiler.target>
	<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
	<java.version>1.8</java.version>
  </properties>
  
  <dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-java-sdk-dynamodb</artifactId>
      <version>1.12.60</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.20</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>DynamoDBLocal</artifactId>
        <version>1.15.0</version>
        <scope></scope>
    </dependency>
  </dependencies>
  <!--Custom repository:-->
  <repositories>
      <repository>
          <id>dynamodb-local</id>
          <name>DynamoDB Local Release Repository</name>
          <url>https://s3-us-west-2.amazonaws.com/dynamodb-local/release</url>
      </repository>
  </repositories>
  <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.10</version>
            <executions>
                <execution>
                    <id>copy</id>
                    <phase>test-compile</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <includeScope>test</includeScope>
                        <includeTypes>so,dll,dylib</includeTypes>
                        <outputDirectory>${project.basedir}/target/native-libs</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
  </build>
</project>

创建LocalDynamoDBCreationRule

package com.jessica.dynamodb.local;

import java.io.IOException;
import java.net.ServerSocket;

import org.junit.rules.ExternalResource;

import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.local.main.ServerRunner;
import com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;

public class LocalDynamoDBCreationRule extends ExternalResource {

	private DynamoDBProxyServer server;
	private DynamoDBMapper dynamoDBMapper;
	private DynamoDB dynamoDB;;

	public LocalDynamoDBCreationRule() {
		// This one should be copied during test-compile time. If project's basedir does
		// not contains a folder
		// named 'native-libs' please try '$ mvn clean install' from command line first
		System.setProperty("sqlite4java.library.path", "target/native-libs");
	}

	@Override
	protected void before() throws Throwable {

		try {
			final String port = getAvailablePort();
			this.server = ServerRunner.createServerFromCommandLineArgs(new String[] { "-inMemory", "-port", port });
			server.start();
			AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
					.withEndpointConfiguration(new EndpointConfiguration("http://localhost:" + port, "ap-southeast-1"))
					.build();
			dynamoDBMapper = new DynamoDBMapper(client);
			dynamoDB = new DynamoDB(client);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	protected void after() {

		if (server == null) {
			return;
		}

		try {
			server.stop();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public DynamoDBMapper getDynamoDBMapper() {
		return dynamoDBMapper;
	}

	public void crateTable(CreateTableRequest request) {
		try {
			System.out.println("Issuing CreateTable request for " + request.getTableName());
			Table table = dynamoDB.createTable(request);
			System.out.println("Waiting for " + request.getTableName() + " to be created...this may take a while...");
			table.waitForActive();
			System.out.println("Create " + request.getTableName() + " success");
		} catch (Exception e) {
			System.err.println("CreateTable request failed for " + request.getTableName());
			System.err.println(e.getMessage());
		}
	}

	private String getAvailablePort() {
		try (final ServerSocket serverSocket = new ServerSocket(0)) {
			return String.valueOf(serverSocket.getLocalPort());
		} catch (IOException e) {
			throw new RuntimeException("Available port was not found", e);
		}
	}
}

创建unit test

以BasicDaoImplTest为例

package com.jessica.dynamodb.local;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;

import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.BillingMode;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.GlobalSecondaryIndex;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.LocalSecondaryIndex;
import com.amazonaws.services.dynamodbv2.model.Projection;
import com.amazonaws.services.dynamodbv2.model.ProjectionType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.SSESpecification;
import com.amazonaws.services.dynamodbv2.model.Tag;
import com.jessica.dynamodb.constant.DynamoDBConstant;
import com.jessica.dynamodb.favorite.dao.BasicDao;
import com.jessica.dynamodb.favorite.dao.impl.BasicDaoImpl;
import com.jessica.dynamodb.favorite.data.LazyLoadResult;
import com.jessica.dynamodb.favorite.dto.TagDto;

public class BasicDaoImplTest {

	@ClassRule
	public static final LocalDynamoDBCreationRule localDynamoDB = new LocalDynamoDBCreationRule();

	BasicDao<TagDto> basicDao = new BasicDaoImpl<>(localDynamoDB.getDynamoDBMapper());

	@BeforeClass
	public static void createTable() {
		// attributes
		List<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>();
		attributeDefinitions
				.add(new AttributeDefinition().withAttributeName(DynamoDBConstant.HASH_KEY).withAttributeType("S"));
		attributeDefinitions
				.add(new AttributeDefinition().withAttributeName(DynamoDBConstant.RANGE_KEY).withAttributeType("S"));
		attributeDefinitions.add(
				new AttributeDefinition().withAttributeName(DynamoDBConstant.GSI_ONE_HASH_KEY).withAttributeType("S"));
		attributeDefinitions.add(
				new AttributeDefinition().withAttributeName(DynamoDBConstant.GSI_ONE_RANGE_KEY).withAttributeType("S"));
		attributeDefinitions.add(
				new AttributeDefinition().withAttributeName(DynamoDBConstant.GSI_TWO_HASH_KEY).withAttributeType("S"));
		attributeDefinitions.add(
				new AttributeDefinition().withAttributeName(DynamoDBConstant.GSI_TWO_RANGE_KEY).withAttributeType("S"));
		attributeDefinitions.add(new AttributeDefinition().withAttributeName(DynamoDBConstant.GSI_THREE_HASH_KEY)
				.withAttributeType("S"));
		attributeDefinitions.add(new AttributeDefinition().withAttributeName(DynamoDBConstant.GSI_THREE_RANGE_KEY)
				.withAttributeType("S"));
		attributeDefinitions.add(
				new AttributeDefinition().withAttributeName(DynamoDBConstant.LSI_ONE_RANGE_KEY).withAttributeType("S"));

		// table key schema
		List<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>();
		keySchema.add(new KeySchemaElement().withAttributeName(DynamoDBConstant.HASH_KEY).withKeyType(KeyType.HASH));
		keySchema.add(new KeySchemaElement().withAttributeName(DynamoDBConstant.RANGE_KEY).withKeyType(KeyType.RANGE));

		// provisioned Throughput
		ProvisionedThroughput provisionedThroughput = new ProvisionedThroughput().withReadCapacityUnits(1L)
				.withWriteCapacityUnits(1L);

		// local secondary index
		List<LocalSecondaryIndex> localSecondaryIndexs = new ArrayList<>();
		List<KeySchemaElement> lsiOneKeySchema = new ArrayList<KeySchemaElement>();
		lsiOneKeySchema
				.add(new KeySchemaElement().withAttributeName(DynamoDBConstant.HASH_KEY).withKeyType(KeyType.HASH));
		lsiOneKeySchema.add(new KeySchemaElement().withAttributeName(DynamoDBConstant.LSI_ONE_RANGE_KEY)
				.withKeyType(KeyType.RANGE));
		localSecondaryIndexs.add(
				new LocalSecondaryIndex().withIndexName(DynamoDBConstant.LSI_ONE_NAME).withKeySchema(lsiOneKeySchema)
						.withProjection(new Projection().withProjectionType(ProjectionType.ALL)));

		// global secondary index
		List<GlobalSecondaryIndex> globalSecondaryIndexs = new ArrayList<>();
		List<KeySchemaElement> gsiOneKeySchema = new ArrayList<KeySchemaElement>();
		gsiOneKeySchema.add(
				new KeySchemaElement().withAttributeName(DynamoDBConstant.GSI_ONE_HASH_KEY).withKeyType(KeyType.HASH));
		gsiOneKeySchema.add(new KeySchemaElement().withAttributeName(DynamoDBConstant.GSI_ONE_RANGE_KEY)
				.withKeyType(KeyType.RANGE));
		List<KeySchemaElement> gsiTwoKeySchema = new ArrayList<KeySchemaElement>();
		gsiTwoKeySchema.add(
				new KeySchemaElement().withAttributeName(DynamoDBConstant.GSI_TWO_HASH_KEY).withKeyType(KeyType.HASH));
		gsiTwoKeySchema.add(new KeySchemaElement().withAttributeName(DynamoDBConstant.GSI_TWO_RANGE_KEY)
				.withKeyType(KeyType.RANGE));
		List<KeySchemaElement> gsiThreeKeySchema = new ArrayList<KeySchemaElement>();
		gsiThreeKeySchema.add(new KeySchemaElement().withAttributeName(DynamoDBConstant.GSI_THREE_HASH_KEY)
				.withKeyType(KeyType.HASH));
		gsiThreeKeySchema.add(new KeySchemaElement().withAttributeName(DynamoDBConstant.GSI_THREE_RANGE_KEY)
				.withKeyType(KeyType.RANGE));
		globalSecondaryIndexs.add(new GlobalSecondaryIndex().withIndexName(DynamoDBConstant.GSI_ONE_NAME)
				.withKeySchema(gsiOneKeySchema).withProjection(new Projection().withProjectionType(ProjectionType.ALL))
				.withProvisionedThroughput(provisionedThroughput));
		globalSecondaryIndexs.add(new GlobalSecondaryIndex().withIndexName(DynamoDBConstant.GSI_TWO_NAME)
				.withKeySchema(gsiTwoKeySchema).withProjection(new Projection().withProjectionType(ProjectionType.ALL))
				.withProvisionedThroughput(provisionedThroughput));
		globalSecondaryIndexs.add(new GlobalSecondaryIndex().withIndexName(DynamoDBConstant.GSI_THREE_NAME)
				.withKeySchema(gsiThreeKeySchema)
				.withProjection(new Projection().withProjectionType(ProjectionType.ALL))
				.withProvisionedThroughput(provisionedThroughput));

		SSESpecification sseSpecification = new SSESpecification().withEnabled(false);

		Tag tag = new Tag().withKey("product").withValue("local-test");

		CreateTableRequest request = new CreateTableRequest().withTableName("develop.Favorite")
				.withAttributeDefinitions(attributeDefinitions).withKeySchema(keySchema)
				.withBillingMode(BillingMode.PROVISIONED).withProvisionedThroughput(provisionedThroughput)
				.withLocalSecondaryIndexes(localSecondaryIndexs).withGlobalSecondaryIndexes(globalSecondaryIndexs)
				.withSSESpecification(sseSpecification).withTags(tag);
		localDynamoDB.crateTable(request);
	}

	@Test
	public void testSaveLoadDelete() {
		// prepare data
		String userId = "userId1";
		String tagId = UUID.randomUUID().toString();
		String tagName = "firstTag";
		Date now = new Date();
		TagDto newTagDto = TagDto.builder().userId(userId).tagId(tagId).tagName(tagName).createTime(now.getTime())
				.lastAccessTime(now.getTime()).build();
		// run test
		basicDao.save(newTagDto);
		TagDto loadedDto = basicDao.load(newTagDto);
		assertNotNull(loadedDto);

		// clean data
		basicDao.delete(newTagDto);
		loadedDto = basicDao.load(newTagDto);
		assertNull(loadedDto);
	}

	@Test
	public void testBatchSaveLoadDelete() {
		// prepare data
		String userId1 = "userId1";
		String tagId1 = UUID.randomUUID().toString();
		String tagName1 = "firstTag";
		Date date1 = new Date();
		String userId2 = "userId2";
		String tagId2 = UUID.randomUUID().toString();
		String tagName2 = "secondTag";
		Date date2 = new Date();
		TagDto newTagDto1 = TagDto.builder().userId(userId1).tagId(tagId1).tagName(tagName1).createTime(date1.getTime())
				.lastAccessTime(date1.getTime()).build();
		TagDto newTagDto2 = TagDto.builder().userId(userId2).tagId(tagId2).tagName(tagName2).createTime(date2.getTime())
				.lastAccessTime(date2.getTime()).build();
		List<TagDto> dtos = Arrays.asList(newTagDto1, newTagDto2);
		basicDao.batchSave(dtos);

		// run test
		List<TagDto> loadedDtos = basicDao.batchLoad(dtos);
		assertEquals(2, loadedDtos.size());

		// clean data
		basicDao.batchDelete(dtos);

		// run test
		loadedDtos = basicDao.batchLoad(dtos);
		assertEquals(0, loadedDtos.size());
	}

	@Test
	public void testQuery() {
		// prepare data
		String userId1 = "userId1";
		String tagId1 = "firstTag";
		String tagName1 = "firstTag";
		Date date = new Date();
		String tagId2 = "secondTag";
		String tagName2 = "secondTag";
		String tagId3 = "thirdTag";
		String tagName3 = "thirdTag";
		String tagId4 = "fouthTag";
		String tagName4 = "fouthTag";
		String userId2 = "userId2";
		String tagId5 = "fifthTag";
		String tagName5 = "fifthTag";
		TagDto newTagDto1 = TagDto.builder().userId(userId1).tagId(tagId1).tagName(tagName1)
				.createTime(date.getTime() - 10000).lastAccessTime(date.getTime() - 10000).build();
		TagDto newTagDto2 = TagDto.builder().userId(userId1).tagId(tagId2).tagName(tagName2)
				.createTime(date.getTime() - 5000).lastAccessTime(date.getTime() - 5000).build();
		TagDto newTagDto3 = TagDto.builder().userId(userId1).tagId(tagId3).tagName(tagName3)
				.createTime(date.getTime() - 1000).lastAccessTime(date.getTime() - 1000).build();
		TagDto newTagDto4 = TagDto.builder().userId(userId1).tagId(tagId4).tagName(tagName4).createTime(date.getTime())
				.lastAccessTime(date.getTime()).build();
		TagDto newTagDto5 = TagDto.builder().userId(userId2).tagId(tagId5).tagName(tagName5).createTime(date.getTime())
				.lastAccessTime(date.getTime()).build();
		List<TagDto> dtos = Arrays.asList(newTagDto1, newTagDto2, newTagDto3, newTagDto4, newTagDto5);
		basicDao.batchSave(dtos);

		try {
			// test sk desc order with size
			LazyLoadResult<TagDto> lazyLoadResult = basicDao.query(TagDto.class, newTagDto1, false, null, 2);
			assertEquals(2, lazyLoadResult.getLoadedDtos().size());
			assertEquals(true, lazyLoadResult.isHasMore());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(0).getUserId());
			assertEquals(tagId3, lazyLoadResult.getLoadedDtos().get(0).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(1).getUserId());
			assertEquals(tagId2, lazyLoadResult.getLoadedDtos().get(1).getTagId());
			lazyLoadResult = basicDao.query(TagDto.class, newTagDto1, false,
					lazyLoadResult.getLoadedDtos().get(1).getSk(), 3);
			assertEquals(2, lazyLoadResult.getLoadedDtos().size());
			assertEquals(false, lazyLoadResult.isHasMore());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(0).getUserId());
			assertEquals(tagId4, lazyLoadResult.getLoadedDtos().get(0).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(1).getUserId());
			assertEquals(tagId1, lazyLoadResult.getLoadedDtos().get(1).getTagId());

			// test sk aes order with size
			lazyLoadResult = basicDao.query(TagDto.class, newTagDto1, true, null, 2);
			assertEquals(2, lazyLoadResult.getLoadedDtos().size());
			assertEquals(true, lazyLoadResult.isHasMore());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(0).getUserId());
			assertEquals(tagId1, lazyLoadResult.getLoadedDtos().get(0).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(1).getUserId());
			assertEquals(tagId4, lazyLoadResult.getLoadedDtos().get(1).getTagId());
			lazyLoadResult = basicDao.query(TagDto.class, newTagDto1, true,
					lazyLoadResult.getLoadedDtos().get(1).getSk(), 3);
			assertEquals(false, lazyLoadResult.isHasMore());
			assertEquals(2, lazyLoadResult.getLoadedDtos().size());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(0).getUserId());
			assertEquals(tagId2, lazyLoadResult.getLoadedDtos().get(0).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(1).getUserId());
			assertEquals(tagId3, lazyLoadResult.getLoadedDtos().get(1).getTagId());

			// test sk aes order without size
			lazyLoadResult = basicDao.query(TagDto.class, newTagDto1, true, null, null);
			assertEquals(4, lazyLoadResult.getLoadedDtos().size());
			assertEquals(false, lazyLoadResult.isHasMore());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(0).getUserId());
			assertEquals(tagId1, lazyLoadResult.getLoadedDtos().get(0).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(1).getUserId());
			assertEquals(tagId4, lazyLoadResult.getLoadedDtos().get(1).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(2).getUserId());
			assertEquals(tagId2, lazyLoadResult.getLoadedDtos().get(2).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(3).getUserId());
			assertEquals(tagId3, lazyLoadResult.getLoadedDtos().get(3).getTagId());

			lazyLoadResult = basicDao.query(TagDto.class, newTagDto1, true, newTagDto4.getSk(), null);
			assertEquals(2, lazyLoadResult.getLoadedDtos().size());
			assertEquals(false, lazyLoadResult.isHasMore());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(0).getUserId());
			assertEquals(tagId2, lazyLoadResult.getLoadedDtos().get(0).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(1).getUserId());
			assertEquals(tagId3, lazyLoadResult.getLoadedDtos().get(1).getTagId());

			// test sk desc order without size
			lazyLoadResult = basicDao.query(TagDto.class, newTagDto1, false, null, null);
			assertEquals(4, lazyLoadResult.getLoadedDtos().size());
			assertEquals(false, lazyLoadResult.isHasMore());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(0).getUserId());
			assertEquals(tagId3, lazyLoadResult.getLoadedDtos().get(0).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(1).getUserId());
			assertEquals(tagId2, lazyLoadResult.getLoadedDtos().get(1).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(2).getUserId());
			assertEquals(tagId4, lazyLoadResult.getLoadedDtos().get(2).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(3).getUserId());
			assertEquals(tagId1, lazyLoadResult.getLoadedDtos().get(3).getTagId());

			lazyLoadResult = basicDao.query(TagDto.class, newTagDto1, false, newTagDto3.getSk(), null);
			assertEquals(3, lazyLoadResult.getLoadedDtos().size());
			assertEquals(false, lazyLoadResult.isHasMore());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(0).getUserId());
			assertEquals(tagId2, lazyLoadResult.getLoadedDtos().get(0).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(1).getUserId());
			assertEquals(tagId4, lazyLoadResult.getLoadedDtos().get(1).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(2).getUserId());
			assertEquals(tagId1, lazyLoadResult.getLoadedDtos().get(2).getTagId());
		} catch (Exception e) {
			throw e;
		} finally {
			// clean data
			basicDao.batchDelete(dtos);
		}
	}

	@Test
	public void testQueryIndex() {
		// prepare data
		String userId1 = "userId1";
		String tagId1 = UUID.randomUUID().toString();
		String tagName1 = "firstTag";
		Date date = new Date();
		String tagId2 = UUID.randomUUID().toString();
		String tagName2 = "secondTag";
		String tagId3 = UUID.randomUUID().toString();
		String tagName3 = "thirdTag";
		String tagId4 = UUID.randomUUID().toString();
		String tagName4 = "fouthTag";
		TagDto newTagDto1 = TagDto.builder().userId(userId1).tagId(tagId1).tagName(tagName1)
				.createTime(date.getTime() - 10000).lastAccessTime(date.getTime() - 10000).build();
		basicDao.save(newTagDto1);
		TagDto newTagDto2 = TagDto.builder().userId(userId1).tagId(tagId2).tagName(tagName2)
				.createTime(date.getTime() - 5000).lastAccessTime(date.getTime() - 5000).build();
		basicDao.save(newTagDto2);
		TagDto newTagDto3 = TagDto.builder().userId(userId1).tagId(tagId3).tagName(tagName3)
				.createTime(date.getTime() - 1000).lastAccessTime(date.getTime() - 1000).build();
		basicDao.save(newTagDto3);
		TagDto newTagDto4 = TagDto.builder().userId(userId1).tagId(tagId4).tagName(tagName4).createTime(date.getTime())
				.lastAccessTime(date.getTime()).build();
		List<TagDto> dtos = Arrays.asList(newTagDto1, newTagDto2, newTagDto3, newTagDto4);
		basicDao.batchSave(dtos);
		try {
			// test tag name desc order
			LazyLoadResult<TagDto> lazyLoadResult = basicDao.queryIndex(TagDto.class, DynamoDBConstant.GSI_ONE_NAME,
					DynamoDBConstant.GSI_ONE_RANGE_KEY, true, TagDto.builder().userId(userId1).build(), false, null, 3);
			assertEquals(3, lazyLoadResult.getLoadedDtos().size());
			assertEquals(true, lazyLoadResult.isHasMore());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(0).getUserId());
			assertEquals(tagId3, lazyLoadResult.getLoadedDtos().get(0).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(1).getUserId());
			assertEquals(tagId2, lazyLoadResult.getLoadedDtos().get(1).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(2).getUserId());
			assertEquals(tagId4, lazyLoadResult.getLoadedDtos().get(2).getTagId());
			lazyLoadResult = basicDao.queryIndex(TagDto.class, DynamoDBConstant.GSI_ONE_NAME,
					DynamoDBConstant.GSI_ONE_RANGE_KEY, true, TagDto.builder().userId(userId1).build(), false,
					lazyLoadResult.getLastLoadPos(), 3);
			assertEquals(1, lazyLoadResult.getLoadedDtos().size());
			assertEquals(false, lazyLoadResult.isHasMore());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(0).getUserId());
			assertEquals(tagId1, lazyLoadResult.getLoadedDtos().get(0).getTagId());

			// test load all
			lazyLoadResult = basicDao.queryIndex(TagDto.class, DynamoDBConstant.GSI_ONE_NAME,
					DynamoDBConstant.GSI_ONE_RANGE_KEY, true, TagDto.builder().userId(userId1).build(), false, null,
					null);
			assertEquals(4, lazyLoadResult.getLoadedDtos().size());
			assertEquals(false, lazyLoadResult.isHasMore());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(0).getUserId());
			assertEquals(tagId3, lazyLoadResult.getLoadedDtos().get(0).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(1).getUserId());
			assertEquals(tagId2, lazyLoadResult.getLoadedDtos().get(1).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(2).getUserId());
			assertEquals(tagId4, lazyLoadResult.getLoadedDtos().get(2).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(3).getUserId());
			assertEquals(tagId1, lazyLoadResult.getLoadedDtos().get(3).getTagId());

			// test tag name aes order
			lazyLoadResult = basicDao.queryIndex(TagDto.class, DynamoDBConstant.GSI_ONE_NAME,
					DynamoDBConstant.GSI_ONE_RANGE_KEY, true, TagDto.builder().userId(userId1).build(), true, null, 3);
			assertEquals(3, lazyLoadResult.getLoadedDtos().size());
			assertEquals(true, lazyLoadResult.isHasMore());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(0).getUserId());
			assertEquals(tagId1, lazyLoadResult.getLoadedDtos().get(0).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(1).getUserId());
			assertEquals(tagId4, lazyLoadResult.getLoadedDtos().get(1).getTagId());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(2).getUserId());
			assertEquals(tagId2, lazyLoadResult.getLoadedDtos().get(2).getTagId());
			lazyLoadResult = basicDao.queryIndex(TagDto.class, DynamoDBConstant.GSI_ONE_NAME,
					DynamoDBConstant.GSI_ONE_RANGE_KEY, true, TagDto.builder().userId(userId1).build(), true,
					lazyLoadResult.getLastLoadPos(), 3);
			assertEquals(false, lazyLoadResult.isHasMore());
			assertEquals(1, lazyLoadResult.getLoadedDtos().size());
			assertEquals(userId1, lazyLoadResult.getLoadedDtos().get(0).getUserId());
			assertEquals(tagId3, lazyLoadResult.getLoadedDtos().get(0).getTagId());
		} catch (Exception e) {
			throw e;
		} finally {
			// clean data
			basicDao.batchDelete(dtos);
		}
	}
}

完整代码

https://github.com/JessicaWin/dynamodb-in-action/tree/local-dynamodb-test

发表评论:

Copyright Your WebSite.Some Rights Reserved.