I have a question concerning the use of EasyMock in junits. We have configured a framework for junits which uses inmemory derby database and EasyMock to test our service project. We use in memory derby for dao layer completely. The question arises on weather to use EasyMock completely or easymock and derby together in the service layer. Below is the scenario :
//class under test is in user-service project
class ServiceClassUnderTest {
IUserService userService;
IAddressService addressService;
public Address getUsersAddress(String id) {
User user = userService.getUserById(id);
// some logic goes here
Address address = addressService.getAddresdByUser(user);
// some validations goes here
return address;
}
}
The class under test is in user-service project and so is the IUserService interface. While IAddressService interface is in address-service project used as a dependency in user-service project.
Now the problem is in the change of approach suggested by some colleagues.
Approach we used to follow
Prepare test data for userService as its in the same project and mock addressService as its part of a dependency project and we might not have much idea about its behaviour and table structure
Advantage : cleaner approach as we have mimimal code for mocking and test data is in separate sql files
Suggested approach
Mock all services irrespective of its being in the same project or part of a dependency project
Disadvantage : more mocking relevant code then actual test related code, making it difficult to maintain and compromises readability.
The code example given is to only explain the scenario where as in real project we have a lot more complex structure with several service beans in a single class.
Could you please give me your suggestions on which approach is better and why considering the arguments provided by me for both approaches ??
A definitive is hard without have the complete big picture. Assuming you really want unit tests, I usually do this:
Test only the query done to the DB with an actual DB
Mock everything that is used by my tested class.
This "everything" should be no more than 3 or 4 dependencies. Otherwise, I will refactor until I get something that is readable.
Having more test code than production code is normal.
If I end up having trivial code in my tested method, I just don't test it. However, a test can also be used to document. So this is a blurry line.
Related
I am writing junit test cases for a spring boot application. I am having lot of doubts and I have listed them below.
Is it enough to write unit test cases only for service layer?
How to re-use the stubs / mocks created for the models. Each model is created with lot of dependencies. If we don't reuse them, we will be creating the same objects again and again. If we reuse how to accommodate the test values for all test cases?
Is there any best practices when creating the stubs?
Do we need to write the unit test cases for utility methods?
Rest controllers needs unit test cases?
I'll try to give the best general answers, though keep in mind that the specific case might require different approach.
No, generally speaking you should test everything that contains logic which might be subject to maintenance, and therefore unwanted changes.
I'm not quite sure on what is the problem here. The way I understood it, you want to write the stubs/mocks once and use them for multiple tests; maybe, you might use one test class and generate the stubs in a #Before, #BeforeClass annotated methods.
Well, the stub is intended to be used in place of a specific method when provided a given input. So, first, you should identify what inputs your stubbed method is going to receive and be sure you are passing them along (Note: if you provide the wrong inputs the stub won't work). Second, you need to stub the return object or the answer. Anyway, you might need to use sequential stubbing for cases when the method is called multiple times and different returns are required.
Yes, a maintenance change might cause the change in the behavior of such methods heavily affecting the product. You should always use JUnit to constraint the logic. Anyway, utility classes should be trivial and I don't expect it to be difficult for you to test them.
Like I already said, if it contains logic, yes, it should. Anyway I kinda remember there are different frameworks to mock rest calls.
Daniele
This question already has answers here:
Is Unit Testing worth the effort? [closed]
(44 answers)
Closed 8 years ago.
I am very new to junit.I was reading a tutorial on http://docs.spring.io/spring/articles/2007/Spring-MVC-step-by-step/part1.html for spring mvc and I found a test class as below :
1.)
package springapp.web;
import org.springframework.web.servlet.ModelAndView;
import springapp.web.HelloController;
import junit.framework.TestCase;
public class HelloControllerTests extends TestCase {
public void testHandleRequestView() throws Exception{
HelloController controller = new HelloController();
ModelAndView modelAndView = controller.handleRequest(null, null);
assertEquals("hello.jsp", modelAndView.getViewName());
} }
I can not understand why I need to use TestCase of Junit as an extra burden when I can check the same by creating a simple test class.
public class TestStub {
public static void main(String[] args) {
HelloController controller = new HelloController();
ModelAndView modelAndView = controller.handleRequest(null, null);
if(modelAndView.getViewName().equals("hello.jsp")) {
...
}
}
}
Again mentioning that I am a beginner.
You could of course create such a class with a main method and apply your own checks and decide if the test is successful or not.
Then you'd be adding more classes, and more tests and things will get a bit messier. Maybe you'd like to run all tests and see their status as a whole, not stopping at the first one that failed. Maybe you'd like to be able to rerun only the tests that failed. Maybe you'd like to run some config section before all of the test methods in a class, and the list can go on.
At this point you'd start tinkering around trying to extract common reusable stuff and create some sort of framework for your needs, which JUnit, TestNg, etc are already. I guess this sounds a bit like reinventing the wheel.
These frameworks have been around for some time so they have been thoroughly tested and they integrate nicely with IDEs and continuous integration tools. Also many of the communities developing widely used frameworks, such as Spring, have put a lot of work in providing a way to facilitate the integration with test frameworks (custom context-aware runners, mock builders, etc), basically making your life easier.
Test classes are "code" as well, and they also have to be clean and well maintained. Using a known test framework makes it easier for team members to understand what you were trying to express, because it "enforces" a standardised way of doing it. This still requires everyone to learn about it, but you have higher chances of reusing that knowledge when switching workplaces, than if you'd be using your own.
I'm sure there are more reasons, but these came to mind as I was reading your question. Stefan has also made a good point, a lot has changed since 2007 and this evolution has made things simpler both with Spring and JUnit4.
I want to test validation logic in a legacy class. The class uses a method to load effective dates from a config file.
I have written a subclass of the class in question and overridden the config method so I can run my unit test against the subclass with any combination of effective dates.
Is this an appropriate strategy? It strikes me as a clean technique for testing code that you don't want to mess with.
I like it, its the most simple and straight forward way to get this done. And since it is a legacy class, it will not change anymore, so you don't run danger of bumping into the fragile base class problem neither.
It seems to be an appropriate strategy to me. Ofcourse with this override you won't
be able to test the code (in the original class) that loads the config data, but if you have other tests to cover this sceario then I think the approach you outlined is fine.
I am creating a website and using Linq to SQl as a data access layer, and i am willing to make the website can work on both linq to sql and ado entity framework, without changing many things in the other layers: business logic layer or UI layer,
Whats the recommended pattern to achieve this goal? can you explain in brief how to do that?
UPDATE
As answered below that repository pattern will help me a lot,
i checked nerd dinner website and understood it, but i found this code inside:
public class DinnersController : Controller {
IDinnerRepository dinnerRepository;
//
// Dependency Injection enabled constructors
public DinnersController()
: this(new DinnerRepository()) {
}
public DinnersController(IDinnerRepository repository) {
dinnerRepository = repository;
}
Which means as i understood that it declare a dinnerRepository using the interface IDinnerRepository , and in the constructor gave it the DinnerRepository, which will be in my case for example the linq to sql implementation,
My question is if i need to switch to ado.net entity framework, i will need to edit this constructor line or there is a better solution for this?
Update 2
Where should i put this Respository Interface and the classes which implement it in my solution, in the data access layer or in the business layer?
The Repository pattern is a good choice. If you implement it as an interface; then you can change out the concrete classes and not have to change anything else.
The Nerd Dinner walkthrough has an excellent example of the Repository pattern (with interface).
The code you listed there would go in your controller (if you were doing an MVC Application); and you create any class you wanted so long as it implemented the IDinnerRepository interface (or you could have something like an IRepository interface if you wanted to design an interface that everyone had to implement that did the basic CRUD actions, and then implement specific interfaces if you needed more (but let's not go interface crazy).
If you're 'tiering' your application, then that part would go in the "Business Logic" layer, and the Repository would be in the "Data Access Layer". That constructor contract would be the 'loosely' coupled part.
I wound up using a minor variation on the "Repository" pattern. I picked it up from the excellent Nerd Dinner tutorial. You can find the whole tutorial here and the code is on Codeplex.
Don't let all the MVC put you off if your not in an MVC situation, the underlying encapsulation of Linq2SQL is a good one. In a recent update of a codebase I went from Linq2SQL to Linkq2EF and all the changes were nicely dealt with in the repository, no outside code had to be touched.
It is also worth noting that the RIA Services stuff comes with a similar pattern. You point it at Linq2Sql or Linq2EF and it build you a basic layer over it complete with CRUD. That layer is in source code so you could just rip it out and use it in a non RIA project but I just leave it as is and link to it in other projects so I use the layer even if I ignore the over-the-wire abilities.
I don't know if I should test my #Entity-annotated Pojos. After all, there are mainly just generated getters/setters. Should I test them?
When it comes to testing DAOs I'm using all those entities - so they are already propely tested, I guess?
Thanks for your thoughts.
Matt
Can your code contain any bugs? If not, what's the point in testing it? In fact, trying to test it would just introduce new bugs (because your tests could be wrong).
So the conclusion is: You should not test getters and setters without code (i.e. those which just assign or read a field without any additional code).
The exception is: When you manually write those getters/setters because you could have made a typo. But even then, some code will use these and there should be a test for that code which in turn tests whether the getters/setters behave correctly.
The only reason I could think of the write tests would be to test the #Entity annotation itself. Testing the storage and retrieval of values seems like one is doubting a fundamental ability of our programming environment :)