Issue
I haver LibraryTest.java which is a test class. The junit test written in the same class is failing. I want to pass my failing junit only by modifying the source code and without changing anything from junit test
I have class Book.java and Library.java
public class Book {
private int id;
private final String name;
private final String description;
private final Category category;
public Book(int id, String name, String description, Category category) {
super();
this.id = id;
this.name = name;
this.description = description;
this.category = category;
}
public enum Category {
CoreJava,
Electronics,
Python,
Hibernate
}
// getter and setters too are there
}
Library.java
public class Library {
private final Set<Book> books = new HashSet<Book>();
public boolean addBook(final Book book) {
return books.add(book);
}
public Iterator<Book> getBooks() {
return books.iterator();
}
}
The test class LibraryTest.java is as follows . The junit test is failing
public class LibraryTest{
private Library library;
private Book hibernate1 ;
private Book hibernate2 ;
private Book coreJava ;
private Book electronics ;
private Book python;
@Before
public void setUp() {
library = new Library();
hibernate1 = new Book(0, "hibernate1", "hibernate book1", Category.Hibernate);
hibernate2 = new Book(0, "hibernate2", "hibernate book2", Category.Hibernate);
coreJava = new Book(0, "coreJava", "written by x", Category.CoreJava);
electronics = new Book(0, "electronics", "written by y", Category.Electronics);
python = new Book(0, "Python Book", "written by someone", Category.Python);
library.addBook(hibernate1);
library.addBook(hibernate2);
library.addBook(coreJava);
library.addBook(electronics);
library.addBook(python);
}
@Test
public void canSortLibrary() throws Exception {
final Book[] orderedBooks = new Book[] { coreJava, hibernate1, hibernate2, electronics, python};
int i = 0;
final Iterator<Book> books= library.getBooks();
while (books.hasNext()) {
final Book book = books.next();
Assert.assertTrue(book == orderedBooks[i++]);
}
}
}
Solution
According your constraints you need to make your Book
class comparable
in a very particular way.
Book.java
import java.util.Arrays;
public class Book implements Comparable<Book> {
static String specialOrder[] = {"coreJava", "hibernate1", "hibernate2", "electronics", "Python Book"};
private int id;
private final String name;
private final String description;
private final Category category;
public Book(int id, String name, String description, Category category) {
super();
this.id = id;
this.name = name;
this.description = description;
this.category = category;
}
public enum Category {
CoreJava, Electronics, Python, Hibernate
}
@Override
public int compareTo(Book otherBook) {
int index = Arrays.asList(specialOrder).indexOf(name);
int indexOther = Arrays.asList(specialOrder).indexOf(otherBook.getName());
if (index != -1 && indexOther != -1) {
// both book titles are in the special order array
// the indices indicate their order
return Integer.compare(index, indexOther);
}
// at least one book title is not in the special array
// therefore use natural order of String
return name.compareTo(otherBook.getName());
}
// getter and setters too are there
String getName(){return name;}
}
And use a container which maintains the order:
Library.java
import java.util.*;
public class Library {
private final SortedSet<Book> books = new TreeSet<Book>();
public boolean addBook(final Book book) {
return books.add(book);
}
public Iterator<Book> getBooks() {
return books.iterator();
}
}
Now we are set and here we go:
$ javac Book.java Library.java
$ javac -cp .:junit-4.13.2.jar LibraryTest.java
$ java -cp .:junit-4.13.2.jar:hamcrest-all-1.3.jar org.junit.runner.JUnitCore LibraryTest
JUnit version 4.13.2
.
Time: 0,003
OK (1 test)
$
Answered By - Franck
Answer Checked By - Gilberto Lyons (JavaFixing Admin)