We are using MockMvc Framework to test Spring Controllers with JUnit. Controller returns a DefferedResult
.
The mockmvc.perform
looks like bellow
mockMvc.perform(post("/customer")
.accept(APPLICATION_JSON)
.header(AUTH_TOKEN_KEY, "xyz")
.header(FROM_KEY, "[email protected]")
.content(json)
.contentType(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(request().asyncStarted());
And it takes a lot of time. We are Using embedded cassandra and because of that it takes a lot of time.
I tried this as well, but it's same.
MvcResult mvcResult = mockMvc.perform(post("/customer")
.accept(APPLICATION_JSON)
.header(AUTH_TOKEN_KEY, "xyz")
.header(FROM_KEY, "[email protected]")
.content(json)
.contentType(APPLICATION_JSON))
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isOk())
.andExpect(request().asyncStarted());
I've hundreds of tests, because of which the build process is really slow.
Is there a way, using JUnit I can say perform the request and wait for response in another thread to assert the results, Or anyother good way of speeding it up.
Thanks
From a technical point of view MockMvc is not thread-safe and shouldn't be reused.
Integration tests focus on testing how separate parts of the program work together. In the context of applications using a database, integration tests usually require a database to be available and contain data that is convenient to the scenarios intended to be tested.
Learn to use Spring MockMVC to perform integration testing of Spring webmvc controllers. MockMVC class is part of Spring MVC test framework which helps in testing the controllers explicitly starting a Servlet container.
Do you really need the Cassandra/Persistence-Layer of your application for this test?
If the anser is no, or if the answer is no a wide array of tests cases, than you could inject another persitsence repoitory when running tests. To achive this, you could use Spring's built in Profile
functionality and annotate your tests accordingly, for example:
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfile("StubPersistence")
public class WebLayerIntegrationTests {
...
}
You could then have a stubbed version of your Cassanda-Repository for your tests, that are allowed to work with static data:
@Profiles("StubPersistence")
@Repository
public class StubCassandaRepository {
...
}
This class could be backed by a simple data structure like a HashSet
or similar, depdends on your use case. The possibility of this approach depdens heavy on your software architecture, so it might not be possible if you can't stub out your Cassandra depdencies.
I also wonder if you really need hundreds of test, that need your complete application, including the web layer. You can of course significantly speed up your tests by favoring Unit-Tests over Integration-Tests, so that you don't need to initiliaze the Spring-Context. Depends on your application and software architecture as well.
There will also be some testing improvements in Spring-Boot 1.4 that will allow you to specifically initilize single slices of your application for testing (like 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 and not your Persistence-Layer, stub it out instead. If you want to test your Persistence-Layer, start with the interfaces of your Persistence-Layer, don't use your Controllers as the test-interface.
As I mentioned in my question We are Using embedded cassandra and because of that it takes a lot of time.
I tried looking things in cassandra.yaml
file and changed the line below.
commitlog_sync_batch_window_in_ms: 90
to
commitlog_sync_batch_window_in_ms: 1
That's all and the build time was reduced from 30 minutes to 2 minutes.
From cassandra.yaml comments:-
It will wait up to
commitlog_sync_batch_window_in_ms
milliseconds for other writes, before performing the sync.
After reducing this time the wait time was reduced and build time got reduced.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With