Win a copy of Java 9 Revealed this week in the Features new in Java 9 forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

First Unit Test, is this too repetitive?  RSS feed

 
Glenn Jayasuriya
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First time doing unit tests, is this too repetitive? Thanks!


If it is too repetitive, what would you recommend to fix it?
Thanks!
 
Stephan van Hulst
Saloon Keeper
Posts: 7190
118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can eliminate testName and returnedName. Just pass the name directly into the constructor, and pass the result of getName() directly to assertEquals(). Also, move each case to their own test method. One test should test one case. Rename your test methods to explain what they do: testNewRecipe(), testNewRecipeWithEmptyName(), testNewRecipeWithLongName(), testNewRecipeWithSpecialName().
 
Glenn Jayasuriya
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:You can eliminate testName and returnedName. Just pass the name directly into the constructor, and pass the result of getName() directly to assertEquals(). Also, move each case to their own test method. One test should test one case. Rename your test methods to explain what they do: testNewRecipe(), testNewRecipeWithEmptyName(), testNewRecipeWithLongName(), testNewRecipeWithSpecialName().


My test code is in a class called RecipeTest so i don't think i need to write test for each method but I changed my code to this:



Question, these tests are for a method called getName.
Another method called getDirections could also use some of these test methods.
Am I allowed to add code in each test method that covers both the getName and getDireciton method at once?
So instead of called it "getNameSpecialCharacters" for instance I just call it "testSpecalCharacters" or something.
Or can each test method only correspond to one method of code?

Thanks!
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 36634
475
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Glenn,
It is a matter of style. I don't have any problems with a test having multiple assertions that cover the same scenario. Some people believe a test should only have one assertion.

I do have two observations:
1) It appears you are testing the value passed into the constructor is the value returned by getName(). If so, you could create a String variable so you aren't duplicating that String and to make the intent clearer.
2) Does the getName() method have logic in it? If it just returns the value (vs doing conversion/validation), most of your tests are overkill.
 
Glenn Jayasuriya
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeanne Boyarsky wrote:Glenn,
It is a matter of style. I don't have any problems with a test having multiple assertions that cover the same scenario. Some people believe a test should only have one assertion.

I do have two observations:
1) It appears you are testing the value passed into the constructor is the value returned by getName(). If so, you could create a String variable so you aren't duplicating that String and to make the intent clearer.
2) Does the getName() method have logic in it? If it just returns the value (vs doing conversion/validation), most of your tests are overkill.


Ya it's a getter method.
I know now i shouldn't be testing that cause it's a waste of time.
I did have another question though, made  test for something that had logic:



I was reading somewhere that unit tests should be self contained.
Is it ok to declare private variables at the top like this.
Or within each method must I repeat instantiating the object in each one.
This way it's less repetitive but I worry that the object could possibly change between test methods and if it's wrong in one it could affect the other.
If that's the case i might just have to instantiate in each method.
 
Rob Spoor
Sheriff
Posts: 20941
81
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you have a test class that only performs one set of tests with different inputs (but always the same), you can take a look at the Parameterized runner. Here's an example in one of my own projects: PosixFilePermissionSupportTest

The @Parameters method can even perform more complex calculations to determine the test data. For instance, you can get your test data from disk.
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 36634
475
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Glenn Jayasuriya wrote:
Is it ok to declare private variables at the top like this.
Or within each method must I repeat instantiating the object in each one.
This way it's less repetitive but I worry that the object could possibly change between test methods and if it's wrong in one it could affect the other.
If that's the case i might just have to instantiate in each method.

It is fine to have instance variables. Especially for common variables such as this. I generally instantiate them in a @Before method.

Note that state doesn't have to be immutable to be effective. JUnit doesn't run multiple tests in the same instance of a class at the same time. So you are safe.
 
Rob Spoor
Sheriff
Posts: 20941
81
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But you should make sure that each test is standalone. Don't make the outcome of one test depend on how another test updates your instance variables.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!