-1

I'm testing my code using JUnit4 to see if an insertion sort of an array of objects (Word(String a, int b)) is correctly sorting the array. The problem I'm having is that when I run JUnit it fails, giving me an error: "expected {One, 1} but was {One, 1}." If I print out both values I'm comparing before I run the test they are also the same. The code is:

package sort;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class InsertionTest {
    private Word word1;
    private Word word2;
    private Word word3;
    private Word word4;
    private Word wordExpected1;
    private Word wordExpected2;
    private Word wordExpected3;
    private Word wordExpected4; 

    @Before
    public void setUp() throws Exception {
        word1 = new Word("One", 1);
        word2 = new Word("Two", 2);
        word3 = new Word("Three", 3);
        word4 = new Word("Four", 4);
        wordExpected1 = new Word("One", 1);
        wordExpected2 = new Word("Two", 2);
        wordExpected3 = new Word("Three", 3);
        wordExpected4 = new Word("Four", 4);
    }

    @After
    public void tearDown() throws Exception {
    }

    @SuppressWarnings("deprecation")
    @Test
    public void test() {
        Word[] wordList = { word3, word2, word4, word1 };
        Word[] expected = { wordExpected1, wordExpected2, wordExpected3, wordExpected4 };
        Insertion.sortInsert(wordList);
        assertEquals(expected, wordList);
    }
}

The code for the insertionsort:

package sort;
public class Insertion {
/**
 * regular insertion sort
 * @param x - the input array containing scores of words that need to be sorted.
 */
    public static void sortInsert ( Word[] x) {
        int N = x.length;

        for (int i = 1; i < N; i++){
            int tempScore = x[i].getScore();
            String tempWord = x[i].getWord();
            int j;

            for (j = (i - 1); j >= 0 && tempScore < x[j].getScore(); j--){
                x[j + 1].setScore(x[j].getScore());
                x[j + 1].setWord(x[j].getWord());
            }

            x[j + 1].setScore(tempScore);
            x[j + 1].setWord(tempWord);
        }
    }
}

The code for the ADT:

package sort; 
public class Word implements Comparable<Word>{
    private String word;
    private int score;

    public Word(String w, int s){
        this.word = w;
        this.score = s;
    }

    public int getScore(){
        return score;
    }

    public void setScore(int s){
        score = s;
    }

    public String getWord(){
        return word;
    }

    public void setWord(String w){
        word = w;
    }

    @Override
    public int compareTo(Word w){
        if ((this.score) > (w.score)) { return 1; }
        else if ((this.score) < (w.score)) { return -1; }
        return 0;
    }

    public String toString(){
        return ("{" + this.word + "," + this.score + "}");
    }
}

Any help would be appreciated, thank you!

Paul Warnick
  • 903
  • 2
  • 13
  • 26

3 Answers3

3

You're creating two different objects. Just because their attributes have the same value, they are not necessarily equal. To achive this, you need to override the equals() method in class Word.

Thus, add:

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Word other = (Word) obj;
        if (score != other.score)
            return false;
        if (word == null) {
            if (other.word != null)
                return false;
        } else if (!word.equals(other.word))
            return false;
        return true;
    }

Eclipse provides an easy way to do this (semi-)automatically. Open your Word class, select Source -> Generate hashCode() and equals()... Select attributes that should be considered when checking two Word objects for equality.

Also, you should oderride hashCode(). Related questions:

By the way: Might be a copy&paste issue, but implemented methods from interfaces are not being annotated with @Override (as your compareTo() is). @Override annotation would be appropriate for toString() since you override the toSting()-method of class Object.

From @Override Javadoc:

Indicates that a method declaration is intended to override a method declaration in a supertype.

Community
  • 1
  • 1
jp-jee
  • 1,502
  • 3
  • 16
  • 21
  • I understand how to overide the equals method to check if an object is the same as another object. But how would I use equals in my Word class to check if an array of objects equals another array? – Paul Warnick Feb 09 '15 at 22:30
  • No need to worry about that. It's internally called when JUnit compares the arrays for equality. By the way: You should use `assertArrayEquals()`, since `assertEquals()` is deprecated. – jp-jee Feb 09 '15 at 22:50
  • Sorry but could you show me and example of overriding `equals()`. I've tried an number of things and every time JUnit still says fail. I'm not sure if I'm correctly overriding it because if I put `@Override` above it, eclipse tell me pretty much to erase it then run. – Paul Warnick Feb 10 '15 at 00:20
  • Thank you, I was trying something very similar to this but for some reason I couldn't get it to work. Also thank you for the pages on hashcode they were very informative. Lastly the @Overrides in random places are from my professor and for some reason we're not allow to change them. Thanks again! – Paul Warnick Feb 10 '15 at 05:33
1

JUnit's assertEquals depends on you correctly implementing Object.equals(Object), which you didn't do. Implement equals(Object) in Word to make this work.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • JUnit4 actually uses the `hashCode()` method in addition to `equals()`, so both must be overridden for the test to pass. Overriding `equals()` on its own isn't quite enough. – MarsAtomic Jul 15 '20 at 04:46
0

Use Lombok to generate the equal and hashcode method. Then it will work. Your code will also become clean by using Lombok annotations.

S.R
  • 113
  • 11