使用Arquillian测试Spring Data + Spring Boot应用程序(第1部分)

Spring Data的使命是为数据访问提供一个熟悉且一致的,基于Spring的编程模型,同时仍保留基础数据存储的特​​殊特征。 它提供了与一些后端技术的集成,例如JPA,Rest,MongoDB,Neo4J或Redis。

因此,如果您使用的是Spring(引导),那么Spring Data是处理持久层的正确选择。

在下一个示例中,您可以看到使用Spring BootSpring Data Redis有多么简单。

@Controller
@EnableAutoConfiguration
public class PingPongController {

    @Autowired
    StringRedisTemplate redisTemplate;

    @RequestMapping("/{ping}")
    @ResponseBody
    List<String> getPong(@PathVariable("ping") String ping) {

        final ListOperations<String, String> stringStringListOperations = redisTemplate.opsForList();
        final Long size = stringStringListOperations.size(ping);
        return stringStringListOperations.range(ping, 0, size);
    }

    @RequestMapping(value="/{ping}", method = RequestMethod.POST)
    ResponseEntity<?> addPong(@PathVariable("ping") String ping, @RequestBody String pong) {

        final ListOperations<String, String> stringStringListOperations = redisTemplate.opsForList();
        stringStringListOperations.leftPushAll(ping, pong);

        URI location = ServletUriComponentsBuilder
            .fromCurrentRequest()
            .buildAndExpand(ping).toUri();

        return ResponseEntity.created(location).build();
    }


    public static void main(String[] args) {
        SpringApplication.run(PingPongController.class, args);
    }

}
@Configuration
public class RedisConfiguration {

    @Bean
    StringRedisTemplate template(final RedisConnectionFactory connectionFactory) {
        return new StringRedisTemplate(connectionFactory);
    }

}

这是通知,缺省时,Spring数据Redis的配置连接到本地主机和端口6379的重要,但是你可以重写通过设置系统属性(spring.redis.hostspring.redis.port)或环境变量这些值(SPRING_REDIS_HOSTSPRING_REDIS_PORT )。

但是现在是时候为这段代码编写测试了。 您可能会遇到的主要问题是,需要在所有需要执行这些测试的机器(例如开发人员机器或Jenkins从站)中安装Redis服务器。

这本身不是问题,但是当您开始处理越来越多的项目时,您将需要在系统上安装越来越多的数据库,甚至更糟糕的是,与生产所需的版本也不完全相同。

为了避免这个问题,一种可能的解决方案是使用Docker和容器。 因此,您无需依赖于在系统上安装每个数据库,而仅依赖Docker 。 然后,测试仅启动存储库容器,在我们的示例中为Redis,执行测试,最后停止容器。

这就是Arquillian (和Arquillian Cube )在帮助您自动化所有事情的地方。
Arquillian CubeArquillian扩展,可用于管理Arquillian的 Docker容器

要使用Arquillian Cube,您需要在计算机上运行Docker守护程序(它可以是本地的,也可以不是本地的),但是可能是在本地。

默认情况下, Docker服务器使用UNIX套接字与Docker客户端进行通信。 Arquillian Cube将尝试检测其正在运行的操作系统,并将docker -java设置为在Linux上使用UNIX套接字,或者将Windows / Mac上的Boot2Docker / Docker-Machine设置为默认URI,因此您的测试可在多个Docker安装之间移植而且您无需担心对其进行配置, Arquillian Cube可以适应您所安装的内容。
Arquillian Cube提供了三种定义容器的不同方法。

  • 定义docker-compose文件。
  • 定义一个容器对象
  • 使用容器对象DSL

在本文中,使用的是Container Object DSL方法。 要定义一个容器,该容器将在执行测试之前启动,而在编写后仅需编写一段代码后停止。

@ClassRule
public static ContainerDslRule redis = new ContainerDslRule("redis:3.2.6")
                                           .withPortBinding(6379);

在这种情况下,将使用JUnit规则来定义测试中应使用的映像( redis:3.2.6 ),并将Redis端口( 6379 )添加为绑定端口。

完整的测试如下所示:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = PingPongController.class, webEnvironment = RANDOM_PORT)
@ContextConfiguration(initializers = PingPongSpringBootTest.Initializer.class)
public class PingPongSpringBootTest {

    @ClassRule
    public static ContainerDslRule redis = new ContainerDslRule("redis:3.2.6")
                                                .withPortBinding(6379);

    @Autowired
    TestRestTemplate restTemplate;

    @Test
    public void should_get_pongs() {

        // given

        restTemplate.postForObject("/ping", "pong", String.class);
        restTemplate.postForObject("/ping", "pung", String.class);

        // when

        final List<String> pings = restTemplate.getForObject("/ping", List.class);

        // then

        assertThat(pings)
            .hasSize(2)
            .containsExactlyInAnyOrder("pong", "pung");
    }

    public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        @Override
        public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
            EnvironmentTestUtils.addEnvironment("testcontainers", configurableApplicationContext.getEnvironment(),
                "spring.redis.host=" + redis.getIpAddress(),
                "spring.redis.port=" + redis.getBindPort(6379)
            );
        }
    }

}

注意,这是一个使用它们的位和鲍勃进行的简单Spring Boot测试,但是测试中使用Arquillian Cube JUnit Rule来启动和停止Redis映像。

需要注意的最后一件事是测试包含ApplicationContextInitializer的实现,因此我们可以使用Docker数据(Redis容器的主机和绑定端口)配置环境,以便Spring Data Redis可以连接到正确的实例。

最后但并非最不重要的build.gradle文件定义所需的依赖项,如下所示:

buildscript {
    repositories {
        jcenter()
        mavenCentral()
    }

    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.2.RELEASE")
    }
}

plugins {
    id "io.spring.dependency-management" version "1.0.2.RELEASE"
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'

repositories {
    jcenter()
}

project.version = '1.0.0'

dependencyManagement {
    imports {
        mavenBom 'org.jboss.arquillian:arquillian-bom:1.1.13.Final'
    }
}

dependencies {

    compile "org.springframework.boot:spring-boot-starter-web:1.5.2.RELEASE"
    compile 'org.springframework.boot:spring-boot-starter-data-redis:1.5.2.RELEASE'
    testCompile 'org.springframework.boot:spring-boot-starter-test:1.5.2.RELEASE'
    testCompile 'junit:junit:4.12'
    testCompile 'org.arquillian.cube:arquillian-cube-docker-junit-rule:1.2.0'
    testCompile 'org.assertj:assertj-core:3.6.2'
}
您可以在http://arquillian.org/arquillian-cube/上了解有关Arquillian Cube的更多信息。

翻译自: https://www.javacodegeeks.com/2017/04/testing-spring-data-spring-boot-applications-arquillian-part-1.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值