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

一篇文章中 ,我写了关于如何使用Arquillian Cube和 Docker一起测试Spring Data应用程序的信息。 测试看起来像:

@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)
            );
        }
    }

}

该测试只是启动Redis容器,然后使用restTemplatepost方法填充数据,然后执行被测逻辑(测试GET HTTP方法),最后停止Redis容器。
很好,它可以工作,但是那里有几个问题:<

  • 第一个是我们正在使用REST API准备测试的数据集。 这里的问题是,测试失败的原因可能不是因为被测代码失败,而是因为测试的准备工作(数据插入)。
  • 第二个问题是,如果POST端点更改了格式/位置,那么您需要记住在使用它的测试中的任何地方进行更改。
  • 最后一个是每个测试都应离开执行前的环境,因此该测试与所有执行隔离。 问题在于,要以这种方式执行此操作,您需要删除POST插入的先前元素。 这意味着添加DELETE HTTP方法,该方法可能并不总是在端点中实现,或者可能仅限于某些具体用户,因此需要处理特殊的身份验证事项。

为了避免此问题, 创建了Arquillian Persistence Extension (aka APE )。 这与DbUnit迁飞扩展集成了SQL数据库,为NoSQLUnit 没有SQL数据库和邮差集合REST服务,让您可以在测试,真正的考验的情况下使用前填充您的后端和执行测试后清理持久性存储。

此外,填充数据也存储在文件内,因此这意味着可以在所有测试中重复使用,并且在进行任何模式更新时可以轻松进行更改。
让我们看一下文章第1部分的示例,但将其更新为使用APE

@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);

    @Rule
    public ArquillianPersistenceRule arquillianPersistenceRule = new ArquillianPersistenceRule();

    @Autowired
    TestRestTemplate restTemplate;

    @Redis
    @ArquillianResource
    NoSqlPopulator populator;

    @Test
    public void should_get_pongs() {

        // given

        populator.forServer(redis.getIpAddress(), redis.getBindPort(6379))
                 .usingDataSet("pings.json")
                 .execute();

        // when

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

        // then

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

    @After
    public void clean_database() {
        populator.forServer(redis.getIpAddress(), redis.getBindPort(6379))
            .clean();
    }

    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)
            );
        }
    }

}

用于填充Redis实例的文件( pings.json )如下所示:

{
  "data" : [
    {
      "list" : [
        {
          "key" : "ping",
          "values" : [
            {
              "value" : "pong"
            },
            {
              "value" : "pung"
            }
          ]
        }
      ]
    }
  ]
}
请注意,在此测试中,您已将POST调用替换为直接插入到存储中的内容。 这样,您可以避免在插入逻辑(不是被测部件)中可能发生的任何故障。 最终,在每种测试方法之后,都会清理Redis实例,以便其他测试将Redis清理到已知状态。
该项目可以在https://github.com/arquillian-testing-microservices/pingpongbootredis中找到

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值