Maven surefire plugin:
<includes>
<include>**/*Test*.java</include>
Base class:
#autoConfigureMockMvc
#SpringBootTest
#ActiveProfiles("test")
public class ApplicationTests {
}
This class is extended by all test classes, which are usually of following syntex:
#ExtendsWith(SpringExtension.class)
public class ATestClass extends ApplicationTests {
#Test
//test method
}
When I do >mvn clean package
All tests run but for each class the boot application restarts, asif its recreating ApplicationContext for each test (Or something else), so it take an hour for build to complete.
How to run all tests in single go.
Related
Normally, I would test the web layer in a Spring project like this:
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class SpringBootDemoApplicationTests extends AbstractTestNGSpringContextTests {
#LocalServerPort
int randomServerPort;
#Autowired
private TestRestTemplate restTemplate;
However, I currently have a difficult back end that requires a specific #TestConfiguration class to manually instantiate the test dependencies using beans.
This ultimately means that I can't use the #SpringBootTest annotation as it will try to create conflicting beans and fail to instantiate others.
If I am not using the #SpringBootTest annotation, I can manually create the TestRestTemplate instead of autowiring it, but what do I need to do to start the embedded local server on a random port?
I would still continue using #SpringBootTest, and combine that with using #Profile on your configuration classes.
That way you could have a configuration which is only used during tests, by using #ActiveProfiles on your #SpringBootTest classes. In the same way you can turn other config classes on or off depending on whether you want them to load or not.
For example on your test would have the following
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
#ActiveProfiles("unittest")
public class SpringBootDemoApplicationTests extends AbstractTestNGSpringContextTests {
...
}
Then create a configuration class which will instantiate your components the way you want them in test
#Profile("unittest")
#Configuration
public void TestConfiguration {
...
}
And you can use profiles to stop your other configuration class from loading during tests.
#Profile("!unittest")
#Configuration
public void ProdConfiguration {
...
}
I created an integration test for a SpringBoot command line application following step 7 in this example:
Here's my integration test
#RunWith(SpringRunner.class)
#SpringBootTest
#TestPropertySource(locations = "classpath:application.integrationtest.properties")
public class IntegrationTest {
#Autowired
private RequestProcessor requestProcessor;
#Test
public void testRequestProcessor() {
requestProcessor.setStandloneFlag(true);
requestProcessor.processRequest();
}
}
When I run this test it launches the #SpringBootApplication itself, but never runs the #Test method in the integration test. The docs say that this should not happen.
Why does #SpringBootTest ignore my #Test method and launch the application?
I have cucumber working with spring-boot and the context and components are available but #SpringBootApplication.main is not being run so various connections aren't available. Is there a way to make Cucumber invoke the spring-boot main method? This works for the context and components but does not invoke TheApplication.main:
#SpringBootApplication
public class TheApplication {
... connect to stuff
and the steps file:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootApplication
#ContextConfiguration(classes = TheApplication.class, loader = SpringBootContextLoader.class)
#WebAppConfiguration
public class TestCreateSteps {
...
A bit of judicious refactoring solved the issue. Moving connection stuff to the class that needs the connection and using TimeUnit in the test to wait for it to initialise. Test is now working:
#SpringBootTest
#ContextConfiguration()
public class TestCreateSteps {
// Previously controlled by TheApplication
// AccountService now controls itself via application.properties
#Autowired
private AccountService accountService;
...
}
I have a small project that does not contain a class to run a Spring Boot Application. In that class I only have some configuration and some repositories. I would like to test those repositories inside the small project.
For that, I have the following:
#SpringBootTest
#DataJpaTest
public class TaskRepositoryTest extends AbstractTestNGSpringContextTests {
#Autowired
private TaskRepository taskRepository;
#Test
public void test() {
taskRepository.save(new Task("open"));
}
}
But I get the following error
Caused by: java.lang.NoSuchMethodError: org.springframework.boot.jdbc.DataSourceBuilder.findType(Ljava/lang/ClassLoader;)Ljava/lang/Class;
Any idea what I have to do?
This works for me with Spring Boot 2.0.3, H2 and latest RELEASE testng:
#EnableAutoConfiguration
#ContextConfiguration(classes = TaskRepository.class)
#DataJpaTest
public class TaskTest extends AbstractTestNGSpringContextTests {
#Autowired
private TaskRepository taskRepository;
#Test
public void test() {
taskRepository.save(new Task("open"));
}
}
LE:
In the previous version of the answer I've used #SpringBootTest #DataJpaTest but that seems to be the wrong way to do it.
The following message would appear:
[main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither #ContextConfiguration nor #ContextHierarchy found for test class [one.adf.springwithoutapp.TaskTest], using SpringBootContextLoader
Using #ContextConfiguration with #DataJpaTest removes that warning and IntelliJ doesn't mark the mocked taskRepository as Could not autowire. No beans of 'TaskRepository' type found.
I have a Spring application built, like this ...
JSP -> MyController -> MyService -> MyDAO -> TheDatabase
Works great.
Now I want to build a JUnit test to exercise the MyService ... do creates, edits, delete, for santity testing functionality.
I created a JUnit 4 class in my src/test/java/com/mycompany/myapp folder, I run the server, and then I try to run the test.
But it fails because the #Autowired MyService is not getting instantiated.
public class Test1 {
#Autowired
MyService myService;
#Test
public void test() {
myService.doSomething();
}
}
QUESTION: How do I get Spring to instantiate the MyService in my JUnit test?
By adding the following annotations to your test class/dependencies (spring-test) to your project:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(/*...*/)
The server will not be needed/involved at (test) runtime.
And of course additional studies, as proposed by dunni's comment, might help!
=> http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#testing