In Spring dependency injection, how does tight coupling hurt the unit testing? - spring

Somebody explained it to me once that, In spring framework, we program to the interface rather than programming to concerete class, because it leads to tight coupling, and that's problematic in unit testing while doing the mocking.
I understand the tight coupling part based on the example here, but I don't understand how tight coupling is a problem with unit testing and mocking.
Just like the way we mock an interface, we can mock a concerte class. So, how tight coupleing hurts the unit testing?

Related

How test driven development is done in Spring?

As I mentioned in the title, I'm interested in how TDD is done in Spring. I am quite new to the notion of unit testing. I've read some articles about TDD. It is said that in TDD, first the tests are written based on requirements, they fail, then with the correct implementation, they succeed. But what should be tested in Spring? The main question is how they should be tested. I have no clue about how I should start, how to evaluate that what should be tested. I am searching for correct methods or conventions to write test-driven code if there's any.
Thanks in advance
TDD is not dependent on the framework you are using. TDD is about the mindset and designing your code based on the failing requirement that's why we write down tests first.
https://medium.com/#mithunsasidharan/test-driven-development-an-overview-46ebc817d580
The framework like Spring makes it easier to write down test cases using principles like Dependency Inversion. And they also provide all unit testing libraries dependencies.
You can check Mockito, Junit to go ahead with testing your code.
https://site.mockito.org/
I will avoid testing the framework functionalities, I would be more interested to test my business logic in it and TDD helps me deigning in a better way.

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.

Testability in AOP

I'm totally new in AOP world.
After reading some books(ex, spring in action), I have a basic question for AOP -- How can we ensure AOP is still working or not working in existing system especially when the system is changing.
You know in real world, especially when the program is still under implementation, the design is always changing. It might be the big program structure changing, might be the refactor. In a word, the program is always changing.
However, the way we adopt AOP in our program is depend on the implementation detail. (ex, the public/private method name) If the implementation detail is changed, possibly the AOP will not work. What's worse, if we're working in a big team, possibly someone will change some implementation detail on which AOP depends, but he is not aware at all. Then the big question is how we can know the AOP is not working in such case? Is there any compilation guarantee or at least junit case guarantee?
Thanks a lot for answer.
This can be tested with Junit and spring-test, a Junit test class can be written that get's injected with an object from the layer at which your aspect is being applied and mock the layer beneath it.
Then call the object to which the aspect is applied and assert that the results are as expected.
This is an example of how to test if method security (applied via aspects) is working.
The test confirms that an AccessDeniedException is thrown as expected, proving that the aspect is working.
Other aspects could be tested in a similar way using spring-test and mocks.
The only way to really test this is with some automated testing, otherwise, as you have pointed out, people could change implementation detail and break the existing AOP. Spring provides integration testing support that will load the beans from your contianer (and also load your AOP). http://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch10s03.html

choosing Mocking framework for Spring JUnit

I am working in Spring based project. My client has asked to write JUnit test cases for my service and DAO layer.
I have to take a decision regarding the Mocking framework I am going to use and same is to be conveyed to the client as soon as possible.
I have never used any Mocking framework before. I have heard of some like Mockito,JMock,EasyMock etc while googling on net. But didn't get any compelling answer for which one I should use.
So, I need some help choosing the right mocking framework.
As other comments have said, there isn't a definitively right answer for this, but I would definitely suggest going with Mockito, for a few reasons:
It provides much better error descriptions than most of the others. Verifications that fail will return exceptions explaining exactly what other calls occurred, where, and with what arguments, making debugging very simple.
It has a clear advantage over older frameworks like EasyMock: Mockito created and has very effectively implemented a far nicer model for mocking than the old record/replay/verify process that EasyMock, JMock and others follow. This is very intuitive and quite easy to get the hang of, and results in far cleaner and easier to maintain tests.
Its model has also become directly popular in many other languages (e.g. Moq), and is closer to mocking styles in dynamic languages. This makes it pretty simple to find other people familiar with it, and makes it easier for you to later use other tools.
It's rapidly becoming the standard framework used for mocking in Java projects: I work on automated testing in projects for many companies, and I've seen a substantial number of them either already using Mockito, and actively migrating to it. Searching for 'easymock mockito' comes up with many results for migrating to Mockito from EasyMock, and none in the other direction.
There's more details of the exact differences between EasyMock and Mockito at https://code.google.com/p/mockito/wiki/MockitoVSEasyMock.
More generally, I would avoid using frameworks like PowerMock unless absolutely required. PowerMock allows you to mock various elements of the codebase that normal mocking frameworks won't, but the fact you need to mock these is normally a strong indicator of some other underlying design problem. If you find yourself unable to test something without using PowerMock, you should really consider whether the structure of the code being tested could be refactored insteard (e.g. to move away from dependencies on static methods, to better use dependency injection to avoid calling constructors, etc).
I'd also suggest you also read Martin Fowler's excellent introduction to mocking. This is a little outdated now in terms of the frameworks discussed, but does still offers a really great overview to the main concepts with some nice examples.

What is the problem with not using Spring

I am trying to understand Spring. I have read about it and done some tutorials. I kind of get the IoC paradigm and the fact that DI is its implementation in Spring.
My question is this: What do you lose by not using Spring? I understand this is a big question and somewhat subjective. But if you could write a few dot points or give an example of a problem that could occur if Spring was not used, I think that would help me and many other people.
Spring is far more than just another IoC tool (think of DAO related stuffs, convenient MVC support, testing tools, ...). In my opinion, it has gradually grown to a kind of "flavor" of Java. But that's not the point :)
Speaking of IoC/DI, what you loose not using it is the easiest way to gain loose coupling in your application, that is associated to reusability. Obviously, most of people tend to think of reusability of a component in another project, which, in my experience, occurs not that often. Greatest benefit of reusability appears when you have to unittest your code.
Programming through interface and using DI/IoC make unittests so easy that even those who are reluctant to unit test will start loving it.
Loose coupling and benefit in matter of UT is one thing you'll lose.
There are no problems actually. But if you start writing your code you will end up with a homegrown framework much like Spring. The thing you get with using Spring is that the framework is already more generic (than your own) and you can use it in a lot of different projects. And the most important (maybe) is that Spring is well tested with so many users using it.
Of course you can try also another framework not just Spring. There are a lots out there...
I did a write-up on why people use dependency injection frameworks (like Spring and Google Guice). Most tutorials neglect this, but IMHO it is the most important thing.
If you understand the problem you have, and what problems all these patterns/frameworks solve, only then are you able to make good software and great architectural choices.
Read about it here: http://www.redcode.nl/blog/2010/01/dependency-injection-dissection
Put simply, you apply dependency injection to write clean and testable code. Also in return you achieve a design in which the caller knows which implementation to use(inject) rather than callee (this is what's famous as the "Hollywood principle"). Now if you don't use use DI frameworks like Spring and Guice you try to achieve dependency injection using factories. But factories come with a cost of boilerplate code and uneasy clean-up while testing. Some people also find other strengths in these frameworks which is their easy integration with frameworks belonging to different tiers like Struts, Hibernate etcetera.
A glib answer is that you'd have to code it all yourself. I don't know much about Spring (yet), but even the basic act of constructor injection would require a lot of code whereas with Spring you need two edit points:
In config:
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
<spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net">
<object name="mediaLibrary" type="AlbumLibraryWPF.AlbumLibrary, AlbumLibrary"/>
</objects>
</spring>
In code:
IApplicationContext ctx = ContextRegistry.GetContext();
library = (Library)ctx.GetObject("mediaLibrary");
Which would you rather do: write a DI framework yourself or concentrate of building your solution?
Spring is much more than a DI framework. There a lot of areas that it will make programming easier for you:
JDBC, Hibernate, JMS templates (dramatically reduce code line count)
Aspect programming
Security (Spring security)
Spring MVC
Spring Web Services
These are just some examples - there are many more. You don't have to use any of the above, but there all part of a mature, well designed framework and in general they make things easier.
The core of Spring is of course Dependency Injection. The benefits of using a DI framework may not be apparent for small projects, but there are more than evident for large and complicated ones. Martin Fowler explains Inversion of Control very clearly. Of course there other alternatives (Guice for example), but I would say that Spring is now an industry standard.
IoC is mostly a good thing within the Java language because when most applications start growing and you don't design for modularization/loose coupling, you end up with a big pile of interconnected classes without no sensible boundaries.
For starters, Spring and other IoC/DI frameworks makes you think about modularization right from the start. This is big because if you have your code well modularized/loose coupled, you end up componentizing and reusing much more wich leads to better unit testing (if you do unit testing anyway).
If I want to write a DAO, I can define its interface up front:
interface IPersonDao {
List<Person> getPersonsByTeam(String teamName);
}
then, I can just call for the implementation of this interface from anywhere in the src where's Spring is being "applied". Suppose i need it in a service layer:
class MyService {
#Autowired
IPersonDao svc;
}
or in a test class:
class TestPersonDao {
#Autowired
IPersonDao svc;
#Test
void testGetPersons(){
List<Person> persons = svc.getPersonsByTeam("billing");
Assert.assertDataSet(persons, "billing.xml");
}
}
Besides, my Dao implementation can hide the complexities of data access without messing with the Dao contract. If I require a hibernate session or a persistence manager, I just declare that:
class JpaPersonDao implements IPersonDao {
#PersistenceContext
EntityManager em;
List<Person> getPersonsByTeam(String tm) {
em.createQuery("...");
}
}
Componentization of classes requires a registry in order to wire collaborating beans. This could be developed by hand, but there are already DI frameworks that do this. Besides, Spring has alot of other stuff like exception translation, support for aspect programming, mvc frameworks, portlet frameworks, integration with hibernate, jpa and/or other db stacks which of course integrate nicely with the Spring IoC stuff.

Resources