Win a copy of Spring in Action (5th edition) this week in the Spring forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Devaka Cooray
  • Liutauras Vilda
  • Jeanne Boyarsky
Sheriffs:
  • Knute Snortum
  • Junilu Lacar
  • paul wheaton
Saloon Keepers:
  • Ganesh Patekar
  • Frits Walraven
  • Tim Moores
  • Ron McLeod
  • Carey Brown
Bartenders:
  • Stephan van Hulst
  • salvin francis
  • Tim Holloway

How can I unit test method that return String  RSS feed

 
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey guys. I've got method that retrieve data from DataBase and put it in ArrayList. After that I assign it to listOfClients.
I wanna test this method, but I don't know how. Should I mock something there?


Here is storage.getAllCustomers() method:

 
Marshal
Posts: 61715
193
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why have you got a method called printXXX() which doesn't print anything? Why are you trying to turn your List into a single String? Why not simply print the List? Why is your variable name in the for‑each loop listOfClient? That is likely to cause confusion with the List.
 
must Janik
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Why have you got a method called printXXX() which doesn't print anything? Why are you trying to turn your List into a single String? Why not simply print the List? Why is your variable name in the for‑each loop listOfClient? That is likely to cause confusion with the List.



Well... I change name print... to getAllClients.
listOfClients - that's beacuse it contains list of clients

Before modifications, this method printed all clients, but I couldn't write any test for it. That's because I drop it and turn to return String.
My method looked like this:


I gonna answer before you ask about logger. I used it instead of sys.out, because it is so much better. Everyone name it logger, so did I.
 
must Janik
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ups. That is previous version.
 
must Janik
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you can, please tell me what should I change in the last version of the method. Also, I would like to know how can I write unit test for it.
Thanks in advance.
 
Campbell Ritchie
Marshal
Posts: 61715
193
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

This morning, I wrote:Why are you trying to turn your List into a single String?

That is the problem I have with that method: why is it there at all? The only way I can think of testing it is to predict what sort of String it will return, which is very awkward without reading directly from the database. It is also awkward because the method isn't some sort of function; you cannot pass any sort of input to it and predict its output from that input.
 
must Janik
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The main reason of that method is to retrieve data of clients from DB.
Acutally, I don't understand your post at all. Should I re-build this method or should I drop testing it?
 
Rancher
Posts: 3748
40
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

must Janik wrote:The main reason of that method is to retrieve data of clients from DB.
Acutally, I don't understand your post at all. Should I re-build this method or should I drop testing it?



Surely the "data of clients from the DB" is the List<Client>.
What Campbell (and me, to be honest) is trying to understand is why this method is turning that into a String.

If it's to log the Clients, then I would expect a method that takes the List<Client> and turns it into a String (ie formats it) for logging purposes.
 
must Janik
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Dave Tolls wrote:

must Janik wrote:The main reason of that method is to retrieve data of clients from DB.
Acutally, I don't understand your post at all. Should I re-build this method or should I drop testing it?



Surely the "data of clients from the DB" is the List<Client>.
What Campbell (and me, to be honest) is trying to understand is why this method is turning that into a String.

If it's to log the Clients, then I would expect a method that takes the List<Client> and turns it into a String (ie formats it) for logging purposes.



So the method should return listOfClient or should it just print data? Please, tell me, because I stand still and don't know what to do next.

What about it?
 
Campbell Ritchie
Marshal
Posts: 61715
193
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I could have sworn I wrote a reply, but it seems to have valished.

You are starting off well, reading from a database and then creating a List<Client>. That is good. Then you are logging that List, but why have you strayed from the straight and narrow object‑oriented (=OO) path into pulling all the fields out individually? Why aren't you using Client#toString()? Why do you need to log that List at all? You could always write the entire List into a file, but what are you going to do with it afterwards? It is going to be awkward to parse from a String.
I cannot see the point of your having the method to put the List into a single String at all. You will end up with a very long String, which your program will find just as illegible as you will. At least add a line end sequence in your loop, so you will have the different records on different lines. But that String will still be awkward to parse if you ever need to recreate Client objects.
At least your append() call uses the toString() method (indirectly via String#valueOf()), so it is more OO. But are you doing anything you couldn't do faster by calling toString() on your List?

I think I wouldn't write that method at all, but I am not writing the code.
 
must Janik
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I could have sworn I wrote a reply, but it seems to have valished.

You are starting off well, reading from a database and then creating a List<Client>. That is good. Then you are logging that List, but why have you strayed from the straight and narrow object‑oriented (=OO) path into pulling all the fields out individually? Why aren't you using Client#toString()? Why do you need to log that List at all? You could always write the entire List into a file, but what are you going to do with it afterwards? It is going to be awkward to parse from a String.
I cannot see the point of your having the method to put the List into a single String at all. You will end up with a very long String, which your program will find just as illegible as you will. At least add a line end sequence in your loop, so you will have the different records on different lines. But that String will still be awkward to parse if you ever need to recreate Client objects.
At least your append() call uses the toString() method (indirectly via String#valueOf()), so it is more OO. But are you doing anything you couldn't do faster by calling toString() on your List?

I think I wouldn't write that method at all, but I am not writing the code.



The method is needed, because how can I get to know about all clients of database on another way?

I really, really try to understand what is wrong with my method, but can't make it.
I have overriden toString method



As you can see, I've "\n" there.

Why do you need to log that List at all?



Because it's console application. Everything is shown on the console.
I renew my question, should this method return print personal data immediately?
 
Sheriff
Posts: 12747
210
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is a common problem I see often:  You want to test code and are totally focused on testing the code as you have currently designed it. So, you have to find a way to twist and bend your test code so that it can do something meaningful.  The problem here really is with your design. Your design does not lend itself well to being tested. You have too much coupling in your design, too many hard dependencies.  You need to loosen up those dependencies so that you can easily isolate parts of your code for the purpose of unit testing.

This is where design thinking comes in. You have to think, literally, from outside the box.  That is, think about the test code you would like to write first.  What is the simplest way you could test that a String actually corresponds to the contents of a list?

If it were me, I'd imagine this kind of test code:


That is where I would start. From there, I would design the class and the method under test so that it's easy to switch from test-use mode to production-use mode.
 
must Janik
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:This is a common problem I see often:  You want to test code and are totally focused on testing the code as you have currently designed it. So, you have to find a way to twist and bend your test code so that it can do something meaningful.  The problem here really is with your design. Your design does not lend itself well to being tested. You have too much coupling in your design, too many hard dependencies.  You need to loosen up those dependencies so that you can easily isolate parts of your code for the purpose of unit testing.

This is where design thinking comes in. You have to think, literally, from outside the box.  That is, think about the test code you would like to write first.  What is the simplest way you could test that a String actually corresponds to the contents of a list?

If it were me, I'd imagine this kind of test code:


That is where I would start. From there, I would design the class and the method under test so that it's easy to switch from test-use mode to production-use mode.



The project I've made is the first project where I write tests.
The whole problem is that I know what I want to test. I just wanna test  method that is responsible for getting customers from DataBase.

I've written something like this:


What about it?
 
Junilu Lacar
Sheriff
Posts: 12747
210
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tell me exactly what you think you are testing with that code. I'm going to bet that what you think you're testing does not align with what the code is actually testing.
 
must Janik
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And you won. I've read a lot of sites about Mockito, but haven't found this  one.
Im struggling with it bout week, since I get to know that something like Mockito exist.

So..To sum up. Method getAllClients returns String and test looks like this:


What do you think bout that?
 
Junilu Lacar
Sheriff
Posts: 12747
210
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

must Janik wrote:What do you think bout that?


That looks much better. Good job.

Two things:

1. The name of the test method should summarize what the intent of the test is. See my previous example.

2. Try to organize test code using the AAA pattern - Arrange Act Assert. With that pattern in mind, I would move line 16 to be right after line 11. I would also move line 14 to be right before line 19 or eliminate it and inline the expected value in the assertEquals() call itself.
 
this is supposed to be a surprise, but it smells like a tiny ad:
Download Free Java APIs to Work with Office Files and PDF
htttp://www.e-iceblue.com/free-apis.html
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!