wood burning stoves 2.0*
The moose likes Testing and the fly likes Unit testing methods with void return type Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Engineering » Testing
Bookmark "Unit testing methods with void return type" Watch "Unit testing methods with void return type" New topic
Author

Unit testing methods with void return type

Anand A. Parikh
Greenhorn

Joined: May 12, 2009
Posts: 21
Hello,

I am learning unit testing by creating unit tests for the MIT Open Courseware course 6.092.

I have the following two classes. How can I unit test borrowBook(), printAvailableBooks() of Library?

borrowBook() has return type void and changes the status 'borrowed' of Book. I can unit test the case of 'successfully borrowing a book',
but how can I unit test cases of 'book already borrowed' or 'book not in catalog'?

printAvailableBooks() has return type void and it does not change any data.

Thanks,
Anand



Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4442
    
    5

Here at the Ranch, we don't encourage people to give code solutions in response to this kind of question. What we do is ask folks to show what they have tried that isn't working for them, then we ask probing and thought-provoking questions or give guidance on what else they might want to try. So with this in mind, what have you tried that didn't work for you?


Junilu - [How to Ask Questions] [How to Answer Questions]
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4442
    
    5

The Library class is not particularly testable in that it would require looking for the results of System.out.println. My first reaction would be to say "Before I can write meaningful unit tests for this class, I need to refactor or rework it to make it more amenable to automated unit testing." Is there anything that would keep you from doing this?
Anand A. Parikh
Greenhorn

Joined: May 12, 2009
Posts: 21
The assignment in the course was to implement the Library class so that it would execute main() (already provided).
So, I implemented it and it does execute main(). The course does not talk about writing unit tests, that was my own addition to the problem.
After implementing Library class, I did think it was not implemented such that one could write unit tests, hence my posting.
Thanks for clarifying this, I will try to refactor it so that I can write unit tests for it.

Thanks,
Anand
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4442
    
    5

I have looked at the assignment and the main methods provided. If you really want to learn how to write unit tests for this, I can guide you through the process here. You basically want to transform what you have in the main into automated unit tests so that instead of having to inspect the output of the System.out statements, you use JUnit test assertions. I suggest you start a personal project in GitHub for this. That way, we won't have to post long segments of code here.
Jeanne Boyarsky
internet detective
Marshal

Joined: May 26, 2003
Posts: 30076
    
149

Junilu Lacar wrote:The Library class is not particularly testable in that it would require looking for the results of System.out.println. My first reaction would be to say "Before I can write meaningful unit tests for this class, I need to refactor or rework it to make it more amenable to automated unit testing." Is there anything that would keep you from doing this?

I disagree. The method changes the state of a book. Which means the unit test can call the method to get all books and assert on the borrowed status of the book.

(The post was edited since your reply so it is possible it didn't before)


[Blog] [JavaRanch FAQ] [How To Ask Questions The Smart Way] [Book Promos]
Blogging on Certs: SCEA Part 1, Part 2 & 3, Core Spring 3, OCAJP, OCPJP beta, TOGAF part 1 and part 2
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4442
    
    5

Jeanne Boyarsky wrote:I disagree. The method changes the state of a book. Which means the unit test can call the method to get all books and assert on the borrowed status of the book.

I said "not particularly testable..." without mentioning any specific methods. Sure, what you said is true for the methods that take a Book as a parameter and change a book's state. However, writing automated tests for the methods that don't take any parameters is less straightforward. Wouldn't you agree though that the System.out.println() statements need to come out of the class? Some might say "Well, this is not real code, it's just for practice," to which I would say, "That's no excuse for poor form. How you practice determines how you play."
Jeanne Boyarsky
internet detective
Marshal

Joined: May 26, 2003
Posts: 30076
    
149

I was looking at the return book method. It doesn't take a book parameter but does change state on the book list.

Yes, I agree the printlns should go. (Except for the method that is supposed to print the list. On that topic, it could be tested by calling System.setOut() with a mock stream or creating a similar method that passes in a mock one.
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4442
    
    5

Jeanne Boyarsky wrote:Yes, I agree the printlns should go. (Except for the method that is supposed to print the list. On that topic, it could be tested by calling System.setOut() with a mock stream or creating a similar method that passes in a mock one.
Yeah, I thought of saying something about that but it seemed like telling a teenage driver that it's Ok to drive 10mph above the speed limit -- you know it's something they might be able to handle and get away with but it's not a particularly good way to do things.
Anand A. Parikh
Greenhorn

Joined: May 12, 2009
Posts: 21
I changed the methods by removing println() and returning values from the methods. Now, I can write unit tests for the methods.

One question - can I use the Book class to call methods on a Book object OR
do I have to generate mock objects for Book class? (since it is external to Library class)

Jeanne Boyarsky
internet detective
Marshal

Joined: May 26, 2003
Posts: 30076
    
149

It is philosophical. Most people (including me) would say not to mock it out because it is just a POJO (plain old java object.) As a rule, I only mock objects that make database/remove calls OR have some horribly complex logic in them.
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4442
    
    5

I wouldn't mock the Book class.

One thing I can suggest to make it easier for you to test and still have a sane design that adheres to good practice: Keep display concerns separated. That is, code that needs to call System.out.println should be in separate methods. Just because printAvailableBooks is the method called by the main method, it doesn't mean that your tests need to call it too. If you follow the practice of keeping unit test classes in the same package as the class under test, your test code can call package private scoped "helper" methods instead of the public methods that have System.out.println calls in them. This relieves you of the need to check what was displayed with System.out.println and it gives you alternative ways of checking object state and behavior that is easier to use from a unit test.

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Unit testing methods with void return type
 
Similar Threads
Having Trouble Referencing a Method from Anonther Method in Another Class
Problem Adding Different "Book" Objects Into A "Library" Array
Create a class which can manage a collection of objects
Array List is Printing Out the Exact Same Thing