Run another project's web service before start tests - spring

IntelliJ project has two modules: Spring Data Rest app and client. Both apps are Spring bootable apps. I made a lot of tests at client and now before every test iteration I have to run the rest service manually.
Test class looks like that:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {BusinessRepositoryImpl.class})
public class BusinessLogoRepositoryTest {
..
}
Here is the service:
#EnableAutoConfiguration
#ImportResource({
"classpath:spring/persistenceContext.xml"
})
#Import(DataServiceConfiguration.class)
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
So the question is if it's possible somehow to add the context of service to test class and run the service before test's start.

You can create a TestSuite with 2 methods annotated with #BeforeClass and #AfterClass to start the service before the tests and stop it after the tests are done.
Draft code to visualize :) what I mean is below.
#RunWith(SpringJUnit4ClassRunner.class)
#SuiteClasses({UnitTest1.class, UnitTest2.class, ... })
#EnableAutoConfiguration
#ImportResource({
"classpath:spring/persistenceContext.xml"
})
#Import(DataServiceConfiguration.class)
public class TestSuite {
#BeforeClass
public void start() throws Exception {
SpringApplication.run(Application.class, args);
}
#AfterClass
public void start() throws Exception {
SpringApplication.shutdown();
}
}

Related

How to make some setup work before ApplicationEvent listener in test

I have a customized spring-boot-starter which will call some REST APIs when it gets a spring application event of ApplicationReadyEvent, so the configuration class is something like:
#Configuration
public class MySpringBootStarter {
#EventListener(ApplicationReadyEvent.class)
public void init() {
// Call REST APIs here
}
}
Then, I want to test the starter using MockServer which requires creating some expectations before the test runs. The test class may look like as follows:
#ExtendWith(MockServerExtension.class)
#SpringBootTest
#ContextConfiguration
#MockServerSettings(ports = {28787, 28888})
public class MySpringBootStarterTest {
private MockServerClient client;
#BeforeEach
public void beforeEachLifecycleMethod(MockServerClient client) {
this.client = client;
//creating expectations here
}
#Test
void shouldBeTrue() {
assertThat(true).isTrue();
}
#SpringBootApplication
static class MyTest {
public void main(String[] args) {
SpringApplication.run(Test.class, args);
}
}
}
But in fact, the expectations are always created after the ApplicationReadyEvent, viz., the init method of MySpringBootStarter class is called before the the beforeEachLifecycleMethod method in MySpringBootStarterTest class.
How can I make the test work, please?
You can use static block initializer to run required code before SpringContext boots up.

Why is my Spring application run from my spring boot unit test

I have a basic spring data application and I have written a unit test. What appears to happen is that when I run the Spring test my application run method gets called as well. I would like to know why this is and how to stop it please.
I have tried using active profiles but that doesnt fix the problem
#SpringBootApplication
#EntityScan({ "com.demo" })
public class Application implements ApplicationRunner {
#Autowired
private IncrementalLoadRepository repo;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(ApplicationArguments args) throws Exception {
IncrementalLoad incrementalLoad = new IncrementalLoad("fred", Instant.now(), Instant.now(), Instant.now());
repo.save(incrementalLoad);
}
and the unit test........
#RunWith(SpringRunner.class)
#SpringBootTest(classes = { Application.class })
#ActiveProfiles("test")
public class IncrementalLoadServiceTest {
#Autowired
private IncrementalLoadService incrementalLoadService;
#Test
public void checkInitialRecords_incrementalLoad() {
List<IncrementalLoad> incrementalLoads = incrementalLoadService.list();
assertEquals(3, incrementalLoads.size());
}
So I think I found the solution. I created another #SpringBootApplication class in my test folders. Initially that failed but I believe thats because the entity scan annotation pointed to packages where my "production" #SpringBootApplication was. I moved that class up a level and it all seems to work ok now.

Ignore to load XML file from SpringBootApplication

I have a Spring Boot application structure like this:
src/main/java
/main/Application.java
src/main/resource/
/application-context.xml
src/test/java
/main/TestApplication.java
src/test/resource/
/application-context-test.xml
When I start application by Run As Spring Boot Application or Run as Junit
Both application-context.xml and application-context-test.xml were loaded.
But I only want to load application-context.xml in running mode, and application-context-test.xml in testing mode.
The initialisers look like:
#ImportResource("classpath:application-context.xml")
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
#ImportResource("classpath:application-context-test.xml")
public class TestApplication{
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
but they do not work.
Both the XMLs are loaded. How can I resolve this?
Annotate TestApplication with :
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = TestApplication.class)

springboottest how to prevent running application

I have the standard Application class which runs a Spring batch ETL:
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
with my Junit test doing something like:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest
public class MyServiceTest {
#Autowired
MyService myService;
#Test
public void testInsertions() {
//do stuff with assertions
}
}
My problem is that when I execute the junit test, the application also kicks off the ETL then executes the test. How to prevent the application from running?
I think there are a lot of alternatives and it really depends on what you are trying to achieve.
One of the options would be to run your tests with a specific profile, like testing, and configure your ETLs (I'm assuming they are just jobs) to be configured based on some property or specific profile.
For example:
Testing class
#ActiveProfiles("testing")
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest
public class MyServiceTest {
...
}
Job/ETL classes
#Component
#Profile("!testing")
public class JobEtlService {
}
Hope it helps.

spring-boot: Application loads but tests fail

I am experiencing rather strange thing when using Spring Boot. Lets get with it.
I have an app which, when ran from spring-boot:run, loads perfectly fine and I can use my server. However, if I try to run tests (either via launching test from IntelliJ or via surefire plugin) context fails to load.
Issue lies within this class (only relevant part shown):
#RestController
#RequestMapping(
value = "/sa/revisions/"
)
#SuppressWarnings("unchecked")
class RevisionController {
#Autowired
// cant autowire this field
private RepositoryEntityLinks repositoryEntityLinks = null;
/* omitted */
}
And here is my main class:
#EnableAsync
#EnableCaching
#EnableAutoConfiguration
#EnableConfigurationProperties
#Import({
SecurityConfiguration.class,
DataConfiguration.class,
RestConfiguration.class
})
public class SpringAtomApplication {
#Autowired
private DataLoaderManager dataLoaderManager = null;
public static void main(String[] args) {
SpringApplication.run(SpringAtomApplication.class, args);
}
#Bean
public CacheManager cacheManager() {
final GuavaCacheManager manager = new GuavaCacheManager();
manager.setAllowNullValues(false);
return manager;
}
#PostConstruct
private void doPostConstruct() {
this.dataLoaderManager.doLoad();
}
}
As I said, application loads without an issue when ran normally, however when it comes to this simple test, everything falls apart:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = SpringAtomApplication.class)
public class SpringAtomApplicationTests {
#Test
public void contextLoads() {
}
}
Would appreciate any suggestion, because I'd love to start with testing it.
You should set SpringApplicationContextLoader in your test class:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(
classes = SpringAtomApplication.class,
loader = SpringApplicationContextLoader.class)
public class SpringAtomApplicationTests {
#Test
public void contextLoads() {
}
}
With that you can test non-web features (like a repository or a service) or start an fully-configured embedded servlet container and run your tests using MockMvc.
Reference: http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/SpringApplicationContextLoader.html

Resources