在 Spring Boot 中使用不同的弹性指数进行测试

Use different elastic index for test in Spring Boot

我有一个 Spring 引导项目,它使用 ElasticSearch 来存储和索引产品。产品型号为:

@Document(indexName = "products", type = "product")
public class Product {

@Id
public String id;
private String[] barcode;
private String name;
private String description;
private String image;
private String detail;
private double price;
private double gain;
private List<Category> categories;
private Currency currency;
private boolean eliminated;
private String taxDescription;
private double taxRate;
private int taxId;

}

我正在对产品的操作进行集成测试,如搜索、更新等,我需要使用相同的弹性服务器。我正在考虑仅出于测试目的创建一个索引,用一些产品填充它,并在测试后删除它。可能吗?我该怎么做?

我假设您在生产代码中使用众所周知的 Spring Data Repositories。像这样的东西可能存在于你的项目中:

@Repository
public interface ProductRepository extends ElasticsearchRepository<Product, String> {
    Product findByName(String name);
}

因此您可以设置一个小型 集成测试 案例,如下所示:

@SpringBootTest
@RunWith(SpringRunner.class)
public class QueryIndexIT {
    @Autowired
    private ProductRepository repo;
    @Autowired
    private ElasticsearchTemplate template;

    @Test
    public void queryRepo() {
        assertThat(template.indexExists(Product.class)).isTrue();

        Product savedProduct = repo.save(new Product(null, "the name", "n/a"));
        Product foundProduct = repo.findByName("the name");

        assertThat(foundProduct).isEqualTo(savedProduct);
    }
}
}

所以基本上您是 运行使用您熟悉的 Spring 上下文进行此集成测试,可能会通过 application-test.properties.

稍作改动

独立于您网络中任何现实生活中的 ElasticSearch 服务器,您还可以使用 Maven Docker Plugin 解耦自己。请特别注意下面我的 pom.xml 片段中列出的 executions 部分。它在任何集成测试 运行 之前启动一个新的 ElasticSearch 容器,并在测试终止后立即将其删除。因此,您以干净稳定的测试设置开始每个测试周期:

            <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>0.28.0</version>
                <configuration>
                    <showLogs>true</showLogs>
                    <verbose>true</verbose>
                    <removeVolumes>true</removeVolumes>
                    <allContainers>true</allContainers>
                    <images>
                        <image>
                            <name>elasticsearch:6.6.2</name>
                            <alias>elasticsearch</alias>
                            <run>
                                <ports>
                                    <port>9200:9200</port>
                                    <port>9300:9300</port>
                                </ports>
                                <env>
                                    <ES_JAVA_OPTS>-Xms512m -Xmx512m</ES_JAVA_OPTS>
                                    <cluster.name>docker-cluster</cluster.name>
                                    <discovery.type>single-node</discovery.type>
                                </env>
                            </run>
                        </image>
                    </images>
                </configuration>
                <executions>
                    <execution>
                        <id>prepare-containers</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>stop</goal>
                            <goal>start</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>remove-containers</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

您可以在引用的 ElasticSearch Docker 图像 in its description on the Docker Hub.

上找到更多信息

So you noticed, that it is not necessary to create a separate index just for testing purposes. Keep test and production code (and config where possible) closely together to avoid surprises at production runtime.

如果您想解决设置中可能存在的问题,您还可以将您的方法与我在 Github repository.

中为您准备的 运行ning 示例进行比较

Just try it with mvn clean verify -Dit.test=QueryIndexIT. Have fun and come back with your progress or remarks!