Not able to write Test cases for Spring Boot application with actual DB connection from Service to DAO - spring-boot

Can anyone let me know, how to write JUnit test cases for Spring Boot application with actual DB connection?
I mean to say, when we right click on #Test class in src/test/java, and click on Run as JUnit Test, we need to Autowire all the beans of Service and DAO which we had developed in src/main/java and control should flow from #Test class to Service and Service to DAO and queries should be executed using #PersistenceContext Entitymanager and return successfully with the desired results.
The stack specifications
Spring Boot 1.5.10
JPA
Please help me...

You can first refer to the documentation of the SpringBootTest
Spring Boot testing instruments allow you to 'slice' application into pieces, test it separately and test application as a whole. If you want to concentrate on database testing - consider using #DataJpaTest.
As for databases: it is a more common case to use in-memory databases like H2 during testing. But, if you want to test against the real databases, take a look at TestContainers or it's particular implementation (test container spring boot)

Related

How to automate the keycloak setup while running Junit test cases?

I have some Junit test cases in my Spring Boot project. I am using keycloak for getting tokens on the basis of the username and password in order to perform authentication. Now instead of manually deploying the keycloak server while running Junit test cases, I want to automate the keycloak deployment step. I want to ask that is there any Java library through which I can easily start the keycloak, pass the json file that contains all the configuration related to the realm, clients and users and then after running all Junit test cases keycloak automatically stops? Is there any way of doing such thing while running Junit test cases easily?
If you start an external service, this are surely not unit-tests. This is not even integration testing. That's part of end-to-end testing.
With Spring Boot:
the first (unit) are #WebMvcTest (or #WebFluxTest for reactive app) when testing a #Controller or plain JUnit with #ExtendWith(SpringExtension.class) to #EnableMethodSecurity and auto-wire an instrumented instance of the secured #Component (#Service or #Repository with #PreAuthorise, #PostFilter and alike). All external service and all #Components (but the one under test) are mocked and so is the Authentication in the security-context.
the second (integration) are #SpringBootTest which wire together the application #Components (but external services are still mocked / stubbed). It is still possible to #AutoConfigureMockMvc (or #AutoConfigureWebTestClient) and as so, to keep using mocked Authentication.
the last is best to be done without Java (Protractor or whatever end-to-end testing tool)
I answered this subject many times already. To mention a few:
https://stackoverflow.com/a/75465772/619830
How to write unit test for SecurityConfig for spring security
https://stackoverflow.com/a/75376543/619830

Spring integration test has different behaviour when started via IntelliJ run configuration and via mvn verify

I am working on the Spring application based on Spring Boot 2.6.7 (Spring framework version 5.3.19). I noticed that when I run the integration test via IntelliJ run configuration (basically created only by the right clicking on the test method name and choosing Run test) then the same instance of the ApplicationContext is used in the integration test class and in the actual SpringBootApplication which is tested by the integration test.
But when the same integration test is executed from the command line via mvn verify command, then the different instance of the ApplicationContext is active in the Spring Boot Application from the one which is active in the integration test class.
That for example has a consequence that spring data repository which I added as a field to the integration test class with #SpyBean annotation is not not applied in the Spring boot application. In the applicationContext of the integration test class, that spring data repository is registered as a spy but in the application context of the Spring Boot Application there is no spy proxy but the regular repository.
On the other hand when the test is running via IntelliJ run configuration, the applicationContext is same everywhere and the spy bean is active in the Spring Boot Application flow.
So I want to achieve the same behavior when I run mvn verify as I achieve when I run the test from IntelliJ. Any ideas?

Commit internal transactions while debugging JUnit tests in spring boot

I add the #Transactional annotation to my JUnit test class as suggested in the documentation.
However, the test methods are accessing multiple service methods, each being a transaction (and annotated as #Transactional too). Maybe these are not unit tests? anyway, I want my tests to call multiple service methods, no matter how you call them.
Internal transactions in the middle of the test are not committed to the database (because of the Test class #Transactional annotiation), so I can't check the DB while debugging the test after each internal transaction. However, if I remove the #Transactional annotation, the test breaks.
How should I configure the test so that it commits the internal transactions as they occur?
With Spring Framework 3.2.x you can use #Rollback(false) to instruct the Spring TestContext Framework to commit the transaction for your integration test.
Beginning with Spring Framework 4.2 you can use #Commit to achieve the same goal.

Using Spring Boot Configuration in a custom JUnit test runner that does not otherwise use Spring

I have a custom JUnit test runner that executes acceptance-level tests using a test specification format specific to my project. The system under test is using Spring Boot and takes advantage of its configuration facility. I'd like the tests to be able to read the same configuration files in the same way. Obviously, using Spring Boot Configuration itself is an answer.
I'd like to just use Spring Boot Configuration as a stand-alone library, but I'm willing to fire up Spring Boot if that's what it takes. I'm not in control of the top-level application - JUnit is. So, I don't know how to start Spring Boot when I get control inside my test runner.
I've looked at extending SpringJunit4ClassRunner but I can't keep it from looking for #Test annotations and failing when it doesn't find any. I've started to look into merging code from SpringJunit4ClassRunner into my custom runner. Before I go too far down that path, I'd appreciate input from the community.
It sounds like you simply want the application running for a standalone webservice testing. This can be done simply by scripting the "java -jar" command to run the spring boot application. However, I would question why you don't want to leverage the testing tools built into spring boot? You can fire up the entire spring boot application and write some very logical looking tests.
For example a rest api test case:
#Test
public void homePage() throwsException () {
mockMvc.perform(get("/readingList"))
.andExpect(status().isOk())
.andExpect(view().name("readingList"))
.andExpect((model().attribute("books", is(empty()))));
}

Spring boot JPA without Spring data

I'm gradually introducing Spring Boot to a Spring JPA project. My intent was to first introduce Spring Boot, than at some later stage Spring Data, but I was not able to find any examples (nor a suitable starter) that uses Spring Boot + JPA without Spring Data.
How come? Is there any benefit of introducing Spring Boot to Spring JPA project, without Spring Data, or does it make sense only with Spring Data in place.
Any article link or example code would be helpfull and appreciated, thanks
More context
I'm working with a live project so every change introduces risk. We're discussing of moving from XML to JAVA based configuration, and I'm advocating adopting Spring Boot at a same time, but I lack persuasive selling points.
Personally, I want to include Spring Boot on all layers to boost future productivity, but I need to argue better the direct immediate benefits of using it in our Service/DAO module which is at the moment based on Spring/JPA/Hibernate with the good old manual CRUD implementations.
So I need selling points for using Spring Boot on a persistence layer, but ones that span beyond Spring Data (e.g. configuration gains, maintenance, testing...anything)
As folks have said above, there is no Spring Boot JPA. It's either Spring Boot Data JPA, or JPA on its own.
The immediate benefits that I could think of:
With Spring Data JPA you don't write the Dao layer. For all CRUD operations, the CrudRepository interface gives you all you need. When that is not enough, all you have to use is the #Query annotation to fine-tune your SQLs
Configuration by convention. For example, with Spring Boot, just having the H2 dependency in the classpath gets Spring to use the H2 in-memory database, gives you Datasource configuration and transaction management (only at the JPA repository level) by default
Ability to create micro-services. With Spring Boot, you can create micro services that can be deployed and run on a number of boxes with java -jar ...
You can enable annotation-based transaction with one simple annotation: #EnableTransactionManagement
Java configuration over XML. This advantage is not to be underestimated
A lot less code (the DAO layer) means also a lot less maintenance
The native ability to provide a RESTful API around data: https://spring.io/guides/gs/accessing-data-rest/
It all depends where your company is heading for. If they want to deliver business value faster and move towards more a DevOps operating model, then the above advantages should be enough selling points for any organisation
Spring wiht JPA (for example Hibernate) but without Spring-Data-Jpa means that you direct interact with the JPA Entity manager and. Typical you use it to implement your own DAO from it and use the #Respository annotation.
#Respository
public class UserDao {
#PersistenceContext EntityManager em;
public User findUserByLogin(Sting login) {
....
}
}
Even if there is no starter project, you could use a Spring-Data-JPA project, and implement the Repository in this old fashion style. (And then you could show how simple it become when you just write Spring-Data-JPA interfaces)
As far as I known, spring-boot means more convenient not any independent business feature.
In other words, spring-boot helps you to start, configure your application in some automatically way. But you can do that without spring-boot with your own specific configuration.
So, you are going to use spring-boot in your application means you are going to use spring-boot's auto configuration feature with your original application.
Actually, Spring JPA implemented in spring-data-jpa is what you are looking for not spring-boot. Of course, spring-boot can simplify your work dramatically.

Resources