Tester not giving correct answer in NetBeans

  • Thread starter zak100
  • Start date
  • #1
zak100
Gold Member
432
10

Main Question or Discussion Point

Hi,
I want to create test cases for the following class:
Java:
public class PrintGrades {
    String strGrade="";
     String Method(int iMarks){
      if(iMarks > 93){
          strGrade ="A";
         return "A";
      }
      else if(iMarks >83){
          
          return "B";
      } 
      else if(iMarks > 73){
         strGrade ="B";
         return "C";
      }
      return strGrade;
    }
}
I used NetBeans to generate the test class:
Code:
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author HP
*/
public class PrintGradesTest {
    
    public PrintGradesTest() {
    }
    
    @BeforeClass
    public static void setUpClass() {
    }
    
    @AfterClass
    public static void tearDownClass() {
    }
    
    @Before
    public void setUp() {
    }
    
    @After
    public void tearDown() {
    }
    /**
     * Test of Method method, of class PrintGrades.
     */
    @Test
    public void testMethod() {
        System.out.println("Method");
        int iMarks = 0;
        PrintGrades instance = new PrintGrades();
        String expResult = "";
        String result = instance.Method(iMarks);
        assertEquals(expResult, result);
        // TODO review the generated test code and remove the default call to fail.
        fail("The test case is a prototype.");
    }
    
}
However when I am executing the code it's saying that test has failed. I tried with another test:
Code:
public void testMethod() {
        System.out.println("Method");
        int iMarks = 95;
        PrintGrades instance = new PrintGrades();
        String expResult = "A";
        String result = instance.Method(iMarks);
        assertEquals(expResult, result);
        // TODO review the generated test code and remove the default call to fail.
        fail("The test case is a prototype.");
    }
but still it's saying that test failed. Please guide me how to correct this problem.

Zulfi.
 

Answers and Replies

  • #2
11,485
5,014
I don’t see the reason the tests aren’t working but your code is needlessly complicated. The if block return statements are not needed as the final return can handle the return value. It’s always best to have a single exit from a method.

Next when the grade is none of the conditions tested for it should return an F right but your code will return an empty string.

The name of your method “Method” happens to be a class in Java runtime and so should be avoided as a method name. Try renaming it to getLetterGrade(int iMark) notice I started it with a lowercase letter.

The Method naming error may be the reason for Netbeans confusion.

https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Method.html
 
Last edited:
  • #3
11,485
5,014
another thing to watch out for is using a keyword in any language so while instance isn’t a keyword in java it’s still bad practice to use it as a variable name. Programmers strive not to use any English word as a variable or method or class name instead they will conflate two or more words or prefixes to create an identifier. It’d be better to use printGrades or pg as a variable name.

https://en.m.wikipedia.org/wiki/List_of_Java_keywords
 
  • #4
pbuk
Science Advisor
Gold Member
1,318
313
It’d be better to use printGrades or pg as a variable name.
Well it would be, except PrintGrades is a bad name for a class. Classes describe things and should always be named with a noun (and the convention is to use a singular noun) - here I’d use ExamResult. Why is this important? Because later we might want to add another method that is nothing to do with printing grades (for instance to find the number of marks to get the next grade and we might call this method getUpperGradeBoundary).

Also, hard-coding information regarding an object in a method is not a good idea - better would be to store the grade boundaries in an array property and iterate over it with a while loop in the method. These habits are worth getting into, they will make your life much easier and more productive in the long run, and the principals are common to all OO languages, not just Java.
 
  • #5
Ibix
Science Advisor
Insights Author
5,955
4,520
Quick question (my Java is rusty) - how does string comparison work? Does == check the contents of the String or the address of the String object? And does assertEquals() do the right thing?
 
  • #6
11,485
5,014
Well it would be, except PrintGrades is a bad name for a class. Classes describe things and should always be named with a noun (and the convention is to use a singular noun) - here I’d use ExamResult. Why is this important? Because later we might want to add another method that is nothing to do with printing grades (for instance to find the number of marks to get the next grade and we might call this method getUpperGradeBoundary).

Also, hard-coding information regarding an object in a method is not a good idea - better would be to store the grade boundaries in an array property and iterate over it with a while loop in the method. These habits are worth getting into, they will make your life much easier and more productive in the long run, and the principals are common to all OO languages, not just Java.

You missed the point of my post, I'm trying to get him away from using simple english words because of the keyword issue mostly. The use of the variable name matching the Class name is a common theme that programmers follow for locally defined variable of seldom used classes.

Yes, the name of the class is not something I would do either. You can't tell the poster every little detail about what to fix in one post.

I think the OP's real issue is the use of Method in the name of the method but it could be other stuff too that I don't see.
 
  • #7
verty
Homework Helper
2,164
198
I wonder if Method needs to be marked public.
 
  • #8
11,485
5,014
Quick question (my Java is rusty) - how does string comparison work? Does == check the contents of the String or the address of the String object? And does assertEquals() do the right thing?
The address of the string. We use the .equals() method to check string contents. There's also methods for partial compares too:

.startsWith("HELLO");
.endsWith("HELLO");
.contains("HELLO");

Java:
String aloha = "hello";

aloha.equals("HELLO")    --> fails

//   -vs-

aloha.equalsIgnoreCase("HELLO")    --> passes
 
  • #9
11,485
5,014
I wonder if Method needs to be marked public.
Good question although I think Netbeans would have warned you of it unless the OP has ignored these warning markers in the lefthand column. The Method class is integral to Java as part of the reflection feature and as such may be automatically imported to the java namespace especially if the OP added the import java.lang.*; at the start of his program.
 
  • #10
pbuk
Science Advisor
Gold Member
1,318
313
Quick question (my Java is rusty) - how does string comparison work? Does == check the contents of the String or the address of the String object? And does assertEquals() do the right thing?
Good catch, in Java == checks the pointers to the string objects so it will not do what the OP wants. The correct assertion is assertTrue(expResult.equals(result)).
 
  • #11
Ibix
Science Advisor
Insights Author
5,955
4,520
The address of the string. We use the .equals() method to check string contents. There's also methods for partial compares too:

.startsWith("HELLO");
.endsWith("HELLO");
.contains("HELLO");

Java:
String aloha = "hello";

aloha.equals("HELLO")    --> fails

//   -vs-

aloha.equalsIgnoreCase("HELLO")    --> passes
Thanks. So does assertEquals use .equals or ==? Because it'll fail of it's using the address comparison, I think.
 
  • #12
11,485
5,014
assertEquals uses method overloading in that there are versions for string vs string, int vs int .... primitive datatypes:

http://junit.sourceforge.net/javadoc/org/junit/Assert.html

Java:
static void [B][URL='http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(double,%20double)']assertEquals[/URL][/B](double expected, double actual) 
          [B]Deprecated.[/B] [I]Use assertEquals(double expected, double actual, double epsilon) instead[/I]
static void [B][URL='http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(double,%20double,%20double)']assertEquals[/URL][/B](double expected, double actual, double delta) 
          Asserts that two doubles or floats are equal to within a positive delta.
static void [B][URL='http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(long,%20long)']assertEquals[/URL][/B](long expected, long actual) 
          Asserts that two longs are equal.
static void [B][URL='http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(java.lang.Object[],%20java.lang.Object[])']assertEquals[/URL][/B](java.lang.Object[] expecteds, java.lang.Object[] actuals) 
          [B]Deprecated.[/B] [I]use assertArrayEquals[/I]
static void [B][URL='http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(java.lang.Object,%20java.lang.Object)']assertEquals[/URL][/B](java.lang.Object expected, java.lang.Object actual) 
          Asserts that two objects are equal.
static void [B][URL='http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(java.lang.String,%20double,%20double)']assertEquals[/URL][/B](java.lang.String message, double expected, double actual) 
          [B]Deprecated.[/B] [I]Use assertEquals(String message, double expected, double actual, double epsilon) instead[/I]
static void [B][URL='http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(java.lang.String,%20double,%20double,%20double)']assertEquals[/URL][/B](java.lang.String message, double expected, double actual, double delta) 
          Asserts that two doubles or floats are equal to within a positive delta.
static void [B][URL='http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(java.lang.String,%20long,%20long)']assertEquals[/URL][/B](java.lang.String message, long expected, long actual) 
          Asserts that two longs are equal.
static void [B][URL='http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(java.lang.String,%20java.lang.Object[],%20java.lang.Object[])']assertEquals[/URL][/B](java.lang.String message, java.lang.Object[] expecteds, java.lang.Object[] actuals) 
          [B]Deprecated.[/B] [I]use assertArrayEquals[/I]
static void [B][URL='http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(java.lang.String,%20java.lang.Object,%20java.lang.Object)']assertEquals[/URL][/B](java.lang.String message, java.lang.Object expected, java.lang.Object actual) 
          Asserts that two objects are equal.
 
  • #13
verty
Homework Helper
2,164
198
Good catch, in Java == checks the pointers to the string objects so it will not do what the OP wants. The correct assertion is assertTrue(expResult.equals(result)).
I think identical string literals use the same address. So strGrade = "" will have the same address as assertEquals(strGrade, "").

To cut down the number of String objects created in the JVM, the String class keeps a pool of strings. Each time your code create a string literal, the JVM checks the string literal pool first. If the string already exists in the pool, a reference to the pooled instance returns. If the string does not exist in the pool, a new String object instantiates, then is placed in the pool.
PS. Nevertheless, it could fail for no reason if it doesn't do that.
 
  • #14
11,485
5,014
I think identical string literals use the same address. So strGrade = "" will have the same address as assertEquals(strGrade, "").

PS. Nevertheless, it could fail for no reason if it doesn't do that.
The problem is that read in strings won't be in the pool, will have different mem addresses and so contents must be compared to show strings to be equal.
 
Last edited:
  • #15
pbuk
Science Advisor
Gold Member
1,318
313
assertEquals uses method overloading in that there are versions for string vs string, int vs int .... primitive datatypes:

http://junit.sourceforge.net/javadoc/org/junit/Assert.html
I checked that list before posting and there SHOULD be a version for string vs string, but there isn't so either the documentation is wrong or it is not implemented. Tests may still work because of...

I think identical string literals use the same address. So strGrade = "" will have the same address as assertEquals(strGrade, "").
That appears to be the case for some implementations in practice, but it is not part of the language specification so should not be relied on.

The problem is that read in strings won't be in the pool, will have different mem addresses and so contents must be compared to show strings to be equal.
... this may also be true. So
Java:
assertTrue(expResult.equals(result))
is the way to go.
 
  • #16
pbuk
Science Advisor
Gold Member
1,318
313
You can't tell the poster every little detail about what to fix in one post.
I agree, that's why I didn't mention missing static and public declarations, inconsistent use of Hungarian notation etc. etc.
 
  • #17
11,485
5,014
It’s interesting but the java code bases ive seen just don’t use Hungarian notation. It was popular for Windows development and spread throughout their manuals. I think Charles Simonyi worked for Microsoft and pushed that idea on the developers. Once java became more dominant some f these earlier practices were dropped, also the IDE made it unnecessary with its type checking features.
 
  • #18
11,485
5,014
With respect to the listing, I may have deleted the assert for strings as I was trying to get rid of the url references to make it more readable.

I checked no I didn’t. What happens is string compares are mapped to assertequals for two objects and the two objects must support the equals method via the Comparable interface? I think but it just doesn’t say. Next stop look at junit source code.

Here’s the source code

https://github.com/junit-team/junit4/blob/master/src/main/java/junit/framework/Assert.java

You can see the object compare assertequals has no Comparable restriction so it uses magic ie some default feature like all objects have this equals method implemented. The string equals does the right thing in comparing two strings.

Yes it’s true java Objects all have an equals method

https://www.tutorialspoint.com/java/lang/object_equals.htm
 
Last edited:
  • #19
pbuk
Science Advisor
Gold Member
1,318
313
With respect to the listing, I may have deleted the assert for strings as I was trying to get rid of the url references to make it more readable.

I checked no I didn’t. What happens is string compares are mapped to assertequals for two objects and the two objects must support the equals method via the Comparable interface? I think but it just doesn’t say. Next stop look at junit source code.

Here’s the source code

https://github.com/junit-team/junit4/blob/master/src/main/java/junit/framework/Assert.java

You can see the object compare assertequals has no Comparable restriction so it uses magic ie some default feature like all objects have this equals method implemented. The string equals does the right thing in comparing two strings.

Yes it’s true java Objects all have an equals method

https://www.tutorialspoint.com/java/lang/object_equals.htm
That all makes sense, thanks for following it through: I stopped before looking at the source and just relied on the documentation which should be more explicit as it implies a commutative test which expected.equals(actual) is not. Of course if assertEquals didn’t do that there would be no point in assertSame.
 
  • #20
pbuk
Science Advisor
Gold Member
1,318
313
It’s interesting but the java code bases ive seen just don’t use Hungarian notation. It was popular for Windows development and spread throughout their manuals. I think Charles Simonyi worked for Microsoft and pushed that idea on the developers. Once java became more dominant some f these earlier practices were dropped, also the IDE made it unnecessary with its type checking features.
Yes I don’t think Hungarian notation is generally a good thing, particularly in a (fairly) strongly typed language like Java. But if you are going to use it, you should use it consistently whereas the OP had “iMarks” and “result”.
 

Related Threads on Tester not giving correct answer in NetBeans

  • Last Post
Replies
2
Views
2K
Replies
1
Views
2K
Replies
2
Views
833
  • Last Post
Replies
6
Views
11K
  • Last Post
Replies
2
Views
669
  • Last Post
Replies
9
Views
1K
Replies
13
Views
2K
Replies
3
Views
907
Replies
1
Views
6K
Replies
3
Views
3K
Top