使用嵌入式Cassandra加速Spring MockMvc集成测试

时间:2016-03-21 13:30:19

标签: java junit cassandra spring-test

我们正在使用MockMvc Framework来使用JUnit测试Spring Controller。控制器返回DefferedResult

mockmvc.perform看起来像吼叫

mockMvc.perform(post("/customer")
                .accept(APPLICATION_JSON)
                .header(AUTH_TOKEN_KEY, "xyz")
                .header(FROM_KEY, "email@gmail.com")
                .content(json)
                .contentType(APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(request().asyncStarted());

这需要很多时间。 我们正在使用嵌入式cassandra,因此需要花费大量时间。

我也试过这个,但情况一样。

MvcResult mvcResult = mockMvc.perform(post("/customer")
            .accept(APPLICATION_JSON)
            .header(AUTH_TOKEN_KEY, "xyz")
            .header(FROM_KEY, "email@gmail.com")
            .content(json)
            .contentType(APPLICATION_JSON))
            .andReturn();

mockMvc.perform(asyncDispatch(mvcResult))
            .andExpect(status().isOk())
            .andExpect(request().asyncStarted());

我进行了数百次测试,因为构建过程非常缓慢。

有没有办法,使用JUnit我可以说执行请求并等待另一个线程中的响应来断言结果,或者任何其他加速它的好方法。

由于

3 个答案:

答案 0 :(得分:1)

您是否真的需要应用程序的Cassandra / Persistence-Layer进行此测试?

如果anser是no,或者答案不是大量的测试用例,那么在运行测试时你可以注入另一个persitsence repoitory。要实现这一点,您可以使用Spring的内置Profile功能并相应地注释您的测试,例如:

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfile("StubPersistence")
public class WebLayerIntegrationTests {
...
}

然后,您可以为测试准备一个Cassanda-Repository的存根版本,允许使用静态数据:

@Profiles("StubPersistence")
@Repository
public class StubCassandaRepository {
    ...
}

这个类可以由一个简单的数据结构支持,例如HashSet或类似的,在您的用例上使用。这种方法的可能性会降低您的软件体系结构的重要性,因此如果您不能删除Cassandra依赖项,则可能无法实现。

我也想知道你是否真的需要数百次测试,需要你的完整应用,包括网络层。当然,您可以通过集成测试优于单元测试来显着加快测试速度,这样您就不需要初始化Spring-Context。取决于您的应用程序和软件架构。

Spring-Boot 1.4中还将进行一些测试改进,允许您专门为应用程序的单个片段进行测试(如持久性或Web层): https://spring.io/blog/2016/04/15/testing-improvements-in-spring-boot-1-4

所以,我最好的建议是: 如果要测试控制器,请仅测试控制器而不是持久性层,而是将其存根。如果要测试持久层,请从持久层的接口开始,不要将控制器用作测试接口。

答案 1 :(得分:1)

正如我在问题中提到的那样我们正在使用嵌入式cassandra,因此需要花费很多时间。

我尝试查看cassandra.yaml文件中的内容并更改了以下行。

commitlog_sync_batch_window_in_ms: 90

commitlog_sync_batch_window_in_ms: 1

全部,构建时间从30分钟减少到2分钟。

来自cassandra.yaml评论: -

  

在执行同步之前,它将等待commitlog_sync_batch_window_in_ms毫秒进行其他写入。

减少此时间后,等待时间减少,构建时间缩短。

答案 2 :(得分:0)

你在做以下事吗?

  1. 作为" Spring集成测试运行"? e.g。

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = CassandraConfig.class)
    public class BookRepositoryIntegrationTest {
      //
    }
    
  2. 您是否正在使用 @BeforeClass / @ AfterClass` 注释启动和停止嵌入式Casandra服务器? e.g。

    @BeforeClass
    public static void startCassandraEmbedded() { 
        EmbeddedCassandraServerHelper.startEmbeddedCassandra(); 
        Cluster cluster = Cluster.builder()
          .addContactPoints("127.0.0.1").withPort(9142).build();
        Session session = cluster.connect(); 
    }
    
    ... and ...
    
    @AfterClass
    public static void stopCassandraEmbedded() {
        EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
    }
    
  3. 有关详细信息,请参阅http://www.baeldung.com/spring-data-cassandra-tutorial