Reputation: 89
I have a method that calls another method to retrieve data and insert it into the database, how can I test this method in Junit since this method retrieve nothing? Can anyone provide me some example of this situation?
public static void method(){
User user = getUser();
try {
String Query = "INSERT INTO users (USER_ID , Name) VALUES ("
+user.getID()+","+user.getName()+")";
Statement statement = conn.createStatement();
statement.executeUpdate(Query);
} catch (Exception e) {
e.printStackTrace();
}
}
I was thinking to use mock object for user, but I'm not sure how can I check if the user is inserted to the database. please help.
Upvotes: 1
Views: 4033
Reputation: 7534
There are few pointers here but before that, you have to be sure about what's the code under test. The reason I say this is because that will actually make you refactor your code a lot.
For example, for the code below:
public static void method(){
User user = getUser();
try {
String query = "INSERT INTO users (USER_ID , Name) VALUES ("
+user.getID()+","+user.getName()+")";
Statement statement = conn.createStatement();
statement.executeUpdate(query);
} catch (Exception e) {
e.printStackTrace();
}
}
you might want to test following:-
Whether the query string is created properly i.e. a valid SQL as expected?
Should the method never throw an exception as we want to catch all the checked exception?
All the resources are closed once the work is done? e.g. in your method connection is opened but never closed.
Now out of above points, there could be some points with higher importance e.g. ensuring query is built correctly.
So, for that, the query builder code should be pulled out of this method and now you could easily test this query in the separate unit test.
Similarly, you would want to make sure a connection is closed after its job is completed. Hence, you might want to extract this code to a method that accepts a query as param, open connection, performs DB CRUD closes the connection and returns the output. And make sure that you are not repeating this code all the time in different methods.
Now, let's go to the pointers:-
If you at any point think that there is some code inside a method that's not testable till that code is part of the method. Please pull it out to a public / private method and test it.
Never try to test DB persistence as part of a unit test
. The DB drivers etc are already having their own tests and are globally used.
If you think your method
needs to be tested for whether it is called as many times as expected (it's what you want to test
). It's called interaction based testing
You could use mocking (Mockito) and stub out the method under test and then assert how many times the method should be called. See this and this link.
Hope it helps!
Upvotes: 1
Reputation: 131436
Classes should be tested against the expected behavior.
Here testing the return type (even if it had other thing as void
) makes no sense.
Your method performs a SQL query.
So your unit test has to assert the expected side effect on the database : an insertion with the expected values.
Note that to have reproducible and fast tests, you should favor embedded databases for unit testing.
Upvotes: 0