I have developed UI page which has href to external link. Now this external link is built (with db based key values for http request parameters) in a class which extends GenericLink of Tapestry. I am overriding public ILink getLink(IRequestCycle cycle) and public String getHref() methods for that. The developed task is working as expected.
Now I want to write JUnit tests for this class, but I read there is other mechanism for Unit testing in Tapestry but this is again not clear to me w.r.t. GenericLinks.
Any leads to any artical will really help in order to test GenericLink class.
I am currently been assigned to creating Junit tests for a project. I created some test, however after reading up on some best practices I discovered that Junit tests should not affect real data as it can comprise integrity of the data.
One test for example below tests the Editing of an existing user's data in the repository:
#Test
void EditUserTest()
{
UserController userController = new UserController();
List<User> userList = (List<User>) userController.getCurrentUserlist();
RoleController roleController = new RoleController();
List<Role> roleList = (List<Role>) roleController.GetCurrentRolelist();
User selectedUser = userList.get(0);
selectedUser.setLoginName("EditedLoginName");
selectedUser.setFirstName("EditedFirstName");
selectedUser.setLastName("EditedLastName");
selectedUser.setEmployeeID(555555555);
selectedUser.setRole(roleList.get(6));
selectedUser.setAutoLogoutPeriod(6);
selectedUser.setEksSerial("45f869");
selectedUser.setEksLevel(9);
User NonExistent = new User();
assertTrue(userController.EditUser(selectedUser), "Testing edit to User in repository");
assertFalse(userController.EditUser(NonExistent), "Testing edit to Non-Existent User in repository");
User editedUser = userController.GetUser(selectedUser.getID());
assertEquals("EditedLoginName", editedUser.getLoginName(), "Testing edit to User Login name");
assertEquals("EditedFirstName", editedUser.getFirstName(), "Testing edit to User First name");
assertEquals("EditedLastName", editedUser.getLastName(), "Testing edit to User Last name");
assertEquals(55555555, editedUser.getEmployeeID(), "Testing edit to User Employee ID");
assertEquals(roleList.get(6), editedUser.getRole(), "Testing edit to User Role");
assertEquals("45f869", editedUser.getEksSerial(), "Testing edit to User Eks Serial");
assertEquals(9, editedUser.getEksLevel(), "Testing edit to User Eks Level");
}
As you can see I retrieve a list of the current users within the repository and just take the first one. After changing its values I then make the actual edit to the repository using the controller and later retrieve the same user from the repository to compare and see if an edit was actually made. Now how would I test this same thing without actually affecting the real data within the repository?
Unit tests are not supposed to access real data. You need to mock any such data so that the real data is not affected.
The purpose of unit tests is to test the functionality, it isn't dependent on the real data.
You can look into Mockito for mocking objects that exhibit the behavior of actual objects.
This link might be helpful: Official docs
If you are writing unit tests then your tests should only focus on the components you are testing, which means if you are testing controller layer you should not call service or dao layer and use their functionalities.
Let's say you want to test your controller then, you should mock the service layer using Mockito or any other test framework. By mocking you are basically avoiding actual service call and continue with your controller level testing.
This example will help
This question already has an answer here:
DDD - how to rehydrate
(1 answer)
Closed 4 years ago.
After starting using ddd in a project i have the following architecture :
domain model which contains my aggregate root (AR), my entities and my value objects
repository interface (implemented in the infrastructure part)
application services to create, delete and update the AR. The application services used to update the AR work this way : find the AR from an ID in the database, call some methods, then save it in the database
Nb: i have only one AR because it is supposed to be a microservice and i only talk about the "command" side here.
I need 2 ways to instantiate the AR :
one when calling the application service to create the AR from inputs
one when retrieving the existing AR from the database, i don't really want to do all the checks
In the first case i need to create an id, do some check, etc.
In the second case I just want to recreate the AR from the data contained in the database.
How/where am i supposed to do that?
For the creation from input, i can do it in the application service like that (it is a simple example) :
public class CreateUser {
private final UserRepository userRepository;
public User execute(String name) {
User user = new User(UUID.randomUUID(), name);
return userRepository.create(user);
}
}
For loading the AR from the database, i can either :
user the same constructor doing some validation
create a new one without validation (i don't really like the idea of having a constructor in the AR bypassing all the validation)
Any ideas on how to do this elegantly?
You are wrong in the concept of creating a new instance of the aggregate using a constructor when you load it from the database. You don't have to call any constructor nor factory nor validate any fields. Just get it from the repository with a getAggregateOfId method which returns the aggregate already constructed with the state stored in the database.
We have a FormEditor containing four pages: three FormPages and fourth page is XTextEditor as a source page.
Whenever user makes any changes (e.g. changing value in text box) on FormPages, we change EMF model content inside XTextDocument.modify() method as given below:
xtextEditor.getDocument().modify(new IUnitOfWork.Void<XtextResource>() {
#Override
public void process(XtextResource state) throws Exception {
IParseResult parseResult = state.getParseResult();
Assert.isNotNull(parseResult);
EObject rootASTElement = parseResult.getRootASTElement();
if (rootASTElement instanceof MyModel) {
XyzType t = ((MyModel) rootASTElement).getXyzType();
t.setName(name); <- ‘name’ is the new value entered on FormPage text box
}
}
});
Now, we want to get notifications in FormPages, whenever EMF model gets changed when user makes some changes on source page i.e. XTextEditor.
We tried adding IXtextModelListener and IXtextDocumentContentObserver to IXtextDocument; but these get called for every character entered in XTextEditor.
Our requirement is to get notifications only when values in EMF model get changed (and not for text formatting e.g. when whitespace is inserted/removed).
Can somebody please provide some pointers?
Regards,
Akhil
You can use the EMF Client Platform (ECP), which adds an implementation of an Observer Bus to an EMF model.
They implement an own validation service which does what you described:
ecp.view.validation
This is the validation service, which monitors the domain model and
calculates validation errors.
The validation service already uses the Observer Bus of ECP to register to EMF change events. The Observer Bus itself is implemented as an EContentAdapter listening to every change of the model. It already filters the change events and provides them following the Observer Bus pattern to the event bus which you can register. There you only get the events you registered to and not all events as for the EContentAdapter which you have to filter for yourself.
I think they mainly use it to validate models to show results in their EMF Forms GUI. However, you can use the services also standalone.
I have to test some Thrift services using Junit. When I run my tests as a Thrift client, the services modify the server database. I am unable to find a good solution which can clean up the database after each test is run.
Cleanup is important especially because the IDs need to be unique which are currently read form an XML file. Now, I have to manually change the IDs after running tests, so that the next set of tests can run without throwing primary key violation in the database. If I can cleanup the database after each test run, then the problem is completely resolved, else I will have to think about other solutions like generating random IDs and using them wherever IDs are required.
Edit: I would like to emphasize that I am testing a service, which is writing to database, I don't have direct access to the database. But since, the service is ours, I can modify the service to provide any cleanup method if required.
If you are using Spring, everything you need is the #DirtiesContext annotation on your test class.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("/test-context.xml")
#DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class MyServiceTest {
....
}
Unless you as testing specific database actions (verifying you can query or update the database for example) your JUnits shouldn't be writing to a real database. Instead you should mock the database classes. This way you don't actually have to connect and modify the database and therefor no cleanup is needed.
You can mock your classes a couple of different ways. You can use a library such as JMock which will do all the execution and validation work for you. My personal favorite way to do this is with Dependency Injection. This way I can create mock classes that implement my repository interfaces (you are using interfaces for your data access layer right? ;-)) and I implement only the needed methods with known actions/return values.
//Example repository interface.
public interface StudentRepository
{
public List<Student> getAllStudents();
}
//Example mock database class.
public class MockStudentRepository implements StudentRepository
{
//This method creates fake but known data.
public List<Student> getAllStudents()
{
List<Student> studentList = new ArrayList<Student>();
studentList.add(new Student(...));
studentList.add(new Student(...));
studentList.add(new Student(...));
return studentList;
}
}
//Example method to test.
public int computeAverageAge(StudentRepository aRepository)
{
List<Student> students = aRepository.GetAllStudents();
int totalAge = 0;
for(Student student : students)
{
totalAge += student.getAge();
}
return totalAge/students.size();
}
//Example test method.
public void testComputeAverageAge()
{
int expectedAverage = 25; //What the expected answer of your result set is
int actualAverage = computeAverageAge(new MockStudentRepository());
AssertEquals(expectedAverage, actualAverage);
}
How about using something like DBUnit?
Spring's unit testing framework has extensive capabilities for dealing with JDBC. The general approach is that the unit tests runs in a transaction, and (outside of your test) the transaction is rolled back once the test is complete.
This has the advantage of being able to use your database and its schema, but without making any direct changes to the data. Of course, if you actually perform a commit inside your test, then all bets are off!
For more reading, look at Spring's documentation on integration testing with JDBC.
When writing JUnit tests, you can override two specific methods: setUp() and tearDown(). In setUp(), you can set everything thats necessary in order to test your code so you dont have to set things up in each specific test case. tearDown() is called after all the test cases run.
If possible, you could set it up so you can open your database in the setUp() method and then have it clear everything from the tests and close it in the tearDown() method. This is how we have done all testing when we have a database.
Heres an example:
#Override
protected void setUp() throws Exception {
super.setUp();
db = new WolfToursDbAdapter(mContext);
db.open();
//Set up other required state and data
}
#Override
protected void tearDown() throws Exception {
super.tearDown();
db.dropTables();
db.close();
db = null;
}
//Methods to run all the tests
Assuming you have access to the database: Another option is to create a backup of the database just before the tests and restore from that backup after the tests. This can be automated.
If you are using Spring + Junit 4.x then you don't need to insert anything in DB.
Look at
AbstractTransactionalJUnit4SpringContextTests class.
Also check out the Spring documentation for JUnit support.
It's a bit draconian, but I usually aim to wipe out the database (or just the tables I'm interested in) before every test method execution. This doesn't tend to work as I move into more integration-type tests of course.
In cases where I have no control over the database, say I want to verify the correct number of rows were created after a given call, then the test will count the number of rows before and after the tested call, and make sure the difference is correct. In other words, take into account the existing data, then see how the tested code changed things, without assuming anything about the existing data. It can be a bit of work to set up, but let's me test against a more "live" system.
In your case, are the specific IDs important? Could you generate the IDs on the fly, perhaps randomly, verify they're not already in use, then proceed?
I agree with Brainimus if you're trying to test against data you have pulled from a database. If you're looking to test modifications made to the database, another solution would be to mock the database itself. There are multiple implementations of in-memory databases that you can use to create a temporary database (for instance during JUnit's setUp()) and then remove the entire database from memory (during tearDown()). As long as you're not using an vendor-specific SQL, then this is a good way to test modifying a database without touching your real production one.
Some good Java databases that offer in memory support are Apache Derby, Java DB (but it is really Oracle's flavor of Apache Derby again), HyperSQL (better known as HSQLDB) and H2 Database Engine. I have personally used HSQLDB to create in-memory mock databases for testing and it worked great, but I'm sure the others would offer similar results.