Speed ​​Up Spring MockMvc Integration Test with Integrated Cassandra

We use the MockMvc Framework to test Spring controllers using JUnit. The controller returns a DefferedResult .

mockmvc.perform looks below:

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

And it takes a lot of time. We use the built-in cassandra, and because of this, it takes a lot of time.

I also tried, but it’s the same.

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

I have hundreds of tests that make the build process very slow.

Is there a way using JUnit, I can say execute the request and wait for a response in another thread to validate the results, or any other good way to speed it up.

thanks

+6
source share
3 answers

As I mentioned in my question "We use the built-in cassandra, and because of this it takes a lot of time."

I tried looking for things in the cassandra.yaml file and changed the line below.

 commitlog_sync_batch_window_in_ms: 90 

to

 commitlog_sync_batch_window_in_ms: 1 

That everything and assembly time were reduced from 30 minutes to 2 minutes.

From cassandra.yaml comments: -

It will wait until commitlog_sync_batch_window_in_ms milliseconds for other write operations before synchronizing.

After reducing this time, the waiting time decreased and the assembly time decreased.

+1
source

Are you doing the following?

  • Running as a "Spring Integration Test"? eg.

     @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = CassandraConfig.class) public class BookRepositoryIntegrationTest { // } 
  • Are you starting and stopping the Casandra Embedded Server using @ BeforeClass / @ AfterClass annotations? eg.

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

Read more about http://www.baeldung.com/spring-data-cassandra-tutorial

0
source

Do you really need your app's Cassandra / Persistence-Layer for this test?

If anser is not, or if the answer is not a wide range of tests, than you could add another persitsence repository when running the tests. To achieve this, you can use Spring's built-in Profile functionality and annotate your tests accordingly, for example:

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

After that, you could have a missing version of your Cassanda-Repository for your tests that can work with static data:

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

This class can be supported by a simple data structure, such as a HashSet or similar, depdends in your use case. The possibility of this approach greatly affects your software architecture, so it may not be possible if you cannot drown out your Cassandra wraps.

I also wonder if you really need hundreds of tests that need your full application, including the web layer. You can, of course, significantly speed up your tests by choosing Unit-Tests over Integration-Tests, so you don't need to initialize Spring -Context. Depends on your application and software architecture.

There will also be some testing improvements in Spring-Boot 1.4 that allow you to specifically initialize individual fragments of your application for testing (e.g. Persistence or Web-Layer): https://spring.io/blog/2016/04/15/testing- improvements-in-spring-boot-1-4

So my best advice is: If you want to test your controllers, test only your controllers, not the Persistence-Layer level, turn it off instead. If you want to test your Persistence-Layer, start with the interfaces of your Persistence-Layer, do not use your controllers as a test interface.

0
source

All Articles