Should repositories in Spring Boot applications be tested directly? - spring

Not sure if this will be considered a "legitimate question" or "purely opinion based", but is there a "best practice" with regards to directly testing a repository in a Spring Boot application? Or, should any integration testing simply target the associated service?
The reasoning for the question is simply the fact that, for the most part, a repository in a Spring Boot application contains no project-generated code. At best, it contains project-defined method signatures which Spring generates implementations for (assuming correct naming conventions).
Thanks...

If you can mess it up, you should test it. Here the opportunities to mess up can include:
Custom Queries (using #Query) might be wrong (there can be all kinds of logic mistakes or typos writing a query with no compile-time checking)
Repository methods where the query is derived from the method name might not be what you intended.
Arguments passed in, the type on the parameter list might not match the type needed in the query (nothing enforces this at compile time).
In all these cases you're not testing Spring Data JPA, you're testing the functionality you are implementing using Spring Data JPA.
Cases of using provided methods out of the box, like findOne, findAll, save, etc., where your fingerprints are not on it, don't need testing.
It's easy to test this stuff, and better to find the bugs earlier than later.

Yes, I think is a good pratice to do that. You could use #DataJpaTest annotation, it starts a in memory database. The official documentation says:
You can use the #DataJpaTest annotation to test JPA applications. By default, it configures an in-memory embedded database, scans for #Entity classes, and configures Spring Data JPA repositories. Regular #Component beans are not loaded into the ApplicationContext.
Link to the docs: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html

Starting from the idea that repositories should be used only inside services and services are used to interact with the other layers of the system, I would say that testing services should be enough in the majority of cases.
I would not test standard repository methods like findAll, or findBy.., they were tested already and the purpose is not to test JPA, but rather the application.
The only repository methods that should have direct tests are the ones with custom queries. These queries may be located in a shared library and it is not efficient to write similar tests across different projects(in this case regression is a big concern)

Related

Is Java Spring really better than straight up Java programming

I have read that dependency injection is good for testing, in that a class can be tested without its dependencies, but the question comes to my mind if Class A depends on Class B or C or any class, testing Class A independent of some class is yielding a test result of zero, not a failed or past test.
Class A was created to do something and if it is not fed anything whether using new key word or setting up the extra files in Spring, Class A won't do any work.
About the idea of making code modular, readable and maintainable: so business classes became cleaner, but all we did was shift confusion from dirty Java business classes to convoluted XML files and having to delete interfaces used to inject to our loosened objects.
In short, it seems we have to make edits and changes to a file somewhere,right?
Please feel free to put me in my place if my understanding is lacking, just a little irritated with learning Spring because I see the same amount of work just rearranged.
Dependency injection is good for unit testing because you can individually test each method without that method depending on anything else. That way each unit test can test exactly one method.
I would say that if the xml is what’s annoying you check out Spring boot. It’s based on a java configuration so no xml and it simplifies a lot of configuration for you based on your class path. When I first started spring I found the xml very daunting coming from a java background but the annotation based configuration and the auto configuring done by spring boot is extremely helpful for quickly getting applications working.
IMO biggest advantage of using the spring is dependency injection which makes your life easy. For example if you would like to create a new service with three dependencies, then you can create a class very easily using Spring. But without spring, you will end up writing different factory methods which will return you the instances you are looking for. This makes your code very verbose with static method calls. You may want to take a look at the code repositories before spring era.
Again if you would like to use Spring or not is your personal call based on project complexity. But it's other features/advantages cant be overlooked.
And XML files or Java configs are the ways of achieving spring configuration - where you would like to add your business logic is personal flavour. Only thing is you should be consistent all across your project.
I would suggest that you read Martin Fowler's great article on Inversion of Control and Dependency Injection to gain a better understanding of why frameworks like Spring can be really useful to solve a well known set of common dependency injection problems when writing software.
As others have mentioned, there is no obligation to use Spring; and whatever you can do with Spring, you can probably do it by other means like abstract factories, factory methods, or service locators.
If your project is small enough, then you probably wouldn't mind solving the dependency injection issues on your own using some design patterns like those mentioned above. However, depending on the size of your project, many would prefer to use a framework or a library that already packs a bunch of solutions to these recurrent head scratchers.
In regards to the advantages of dependency injection frameworks when doing unit testing is the idea that you don't need to test the dependencies of your class, but only your class.
For example, most likely your application has a layered design. It is very common to have a data access class or a repository that you use to retrieve data from a datasource. Logically, you also have a class where you use that DAO.
Evidently, you already wrote unit testing for your DAO, and therefore, when you're testing your business class (where the DAO is being used) you don't care about testing your DAO again.
Fortunately, since Spring requires some form of dependency injection for your DAO, this means your class must provide a constructor or a setter method through which we can inject that DAO into our business class, right?
Well, then during unit testing of your business class, you can conveniently use those injection points to inject your own fake DAO (i.e. a mock object). That way, you can focus on the testing of your business class and forget about retesting the DAO again.
Now compare this idea with other solutions you may have done on your own:
You inject the dependency directly by instantiating the DAO within your business class.
You use a static factory method within your code to gain access to the DAO.
You use a static method from a service locator within your code to gain access to the DAO.
None of these solutions would make your code easy to test because there is no simple manner to get in the way of choosing exactly what dependency I want injected into my business class while testing it (e.g. how do you change the static factory method to use a fake DAO for testing purposes?).
So, in Spring, using XML configuration or annotations, you can easily have different dependencies being injected into your service object based on a number of conditions. For example, you may have some configurations for testing that evidently would be different than those used in production. And if you have a staging environment, you may even have different XML configurations of dependencies for your application depending on whether it is running in production or integration environments.
This pluggability of dependencies is the key winning factor here in my opinion.
So, as I was saying, my suggestion to you is that you first expand your understanding of what problems Spring core (and in general all dependency injection frameworks) is trying to solve and why it matters, and that will give you a broader perspective and understanding of these problems in a way that you could to determine when it is a good idea to use Spring and when it is not.

Benefits to using Spring templates

What are the enumerated benefits to using the Spring template classes such as RestTemplate, JdbcTemplate, JpaTemplate, JdoTemplate, JndiTemplate JdoTemplate etc?
I'm looking for the general benefits of using these classes as best practice design, for example the thread safeness of these classes. Or if someone could point me to the section of the Spring documentation that discusses the same I would accept that as well.
Less boilerplate code
More cohesive exceptions handling (e.g. JDBC drivers checked exceptions are translated to meaningful runtime exceptions)
Easier and uniform configuration (almost everything can be configured in Spring context files)
Automatized resource management (like, for instance, closing DB connections)
Note, that not all templates are equally useful. For instance jdbcTemplate is a pure gem, I can't live without that (mostly because JDBC is not the best interface one can imagine), on the other hand jpaTemplate does not bring so many advantages.
Note, that if you use given template, your code becomes dependent on Spring interfaces, so Spring is not only dependency mechanism for your application, but becomes also part of it - Spring is no longer easily replacable with something else (Google Guice, CDI). However, given the fact Spring is a pretty good peace of code, I would not be worried about that aspect.

Good strategy for Spring Framework end-to-end testing

So this is a rather "big" question, but what I'm trying to accomplish is the following:
I have a Spring application, MVC, JDBC (MySQL) and JSP running on tomcat.
My objective is to test the entire "stack" using a proper method.
What I have so far is Junit using Selenium to simulate an actual user interacting with the application (requires a dummy account for that), and performing different validations such as, see if element is present in the page, see if the database has a specific value or if a value matches the database.
1st concern is that this is actually using the database so it's hard to test certain scenarios. I would really like to be able to mock the database. Have it emulate specific account configs, data states etc
2nd concern is that given the fact that I use what is in the database, and data is continuously changing, it is hard to predict behavior, and therefore properly asserting
I looked at Spring Test but it allows for testing outside a servlet container, so no JSP and no Javascript testing possible.
I saw DBUtils documentation but not sure if it will help me in this case
So, to my fellow developers, I would like to ask for tips to:
Run selenium tests on top of a mocked database
Allow different configs per test
Keep compatibility with Maven/Gradle
I have started with an ordered autowire feature to support this kind of stubbing.
It's basically an idea that i took over from the Seam framework i was working with in the past but i couldnt find yet a similar thing in spring.
The idea is to have a precedence annotation (fw, app,mock,...) that will be used to resolve the current implementation of an autowired bean. This is easy already in xml but not with java config.
So we have our normal repository beans in with app precedence and a test package stubbing these classes with mock precedence.
If both are in the classpath spring would normally fail with a duplicate bean found exception. In our case the extended beanfactory simply takes the bean with the highest precedence.
Im not sure if the order annotation of spring could be used directly but i prefered to have "well defined" precedence scopes anyway, so it will be clear for our developers what this is about.
! While this is a nice approach to stub so beans for testing i would not use it to replace a database definition but rather go with an inmemory database like hsql, like some previous answers mentionned already. !

Usecase of Spring DAO

I'm wondering what is the typical usecase of Spring DAO where we can easily switch between different persistence frameworks.
Apart from abstracting the boiler-plate code (for JDBC, Hibernate like) Why does any application want to change its ORM frameworks so frequently?
By using a DAO pattern with a distinct DAO interface, this enables you to mock the DAO implementation. With this you improve testability of your code, as you are then able to write tests that do not need database access.
It is not only about frequently being able to switch between ORM frameworks, but is also about reducing effort if you are enforced to change the ORM.
Another reason is, that you might have different data sources like a database, a webservice or the file system for example. In this case you don't abstract the ORM but simply the persistence mechanism in general.
I think the real important idea behind DAOs are that you have just one spot where all data access related code for a particular entity ist located. That makes testing and refactoring of your persistence layer easier and your code is better readable.
Furthermore, it makes the code better readable. Think of a new developer in your team that should implement a feature. If she needs to access the databasase she would look into the dao for data access methods.
If you scatter the data access code in different services the risk is pretty high that someone produces code duplicates.

Spring core container is the basis for complete Spring framework?

All websites state that the Spring core container is the basis for complete Spring framework i.e., it is used across
the all modules like AOP, JDBC module, Web module, etc. As per my understanding, the Spring core container's main purpose is
to inject dependencies, so avoiding the need of factory classes and methods. Is that correct?
Second question: When it is said, Spring core container is the basis for complete Spring framework (e.g., for Spring AOP). As per my understanding, in Spring AOP also, getting the object of classes like
ProxyFactoryBean is achieved by core container. Right?
Thirdly, it is stated that Spring core container avoids the need for programming the use of singletons. How come singleton
classes are avoided by core container?
yep
yep
All beans declared in Spring config files are singleton by default. They are instantiated when your application starts.
First off, your understanding of what you get from Spring is about right. So let's get on to your third question, the interesting one.
The key is it's not that you don't have singletons, it's that they're singletons by configuration. This is a vital difference, as it means you can avoid all the complicated singleton enforcement code (the source of frequent problems) and instead just write exceptionally simple programs that focus on the business end of things. This is particularly important when you are writing a program with non-trivial object lifetimes: for example, in a webapp it makes it very easy to manage the lifespan of objects that hold state associated with a user's session, since if the objects have session scope, they'll be “singleton per user session”. That's enormously easier to work with than many of the alternatives.
The fact that Spring can also help out with transactions is just perfect as transaction handling is distinctly non-trivial, and AOP is the best solution to them in Java that I've seen (other languages have other options open) with Spring supporting a pretty straight-forward way of doing it. Try to do it properly without if you don't believe me. Spring's pretty much wonderful.

Resources