J-Reid J-Reid - 1 month ago 10
Java Question

Errors testing toString Java code

I am trying to write some test code for a "Book" class that gets and sets book information from other classes: ISBN (String), Title (String), Author (String), publishDate (SimpleDateFormat "MMM.dd.yyy"), Price (Double), and Summary content (Blob).When I try to run a toString test on all or part of the code (which I have changed the format and String that should be set countless times):

@Test
public void testToString() {
Book testBook6 = new Book();
Title testTitle6 = new Title("Title: Moby Dick, ");
Author testAuthor6 = new Author("Author: Mark Twain, ");
ISBN testISBN6 = new ISBN("ISBN: 000-00-000-0000-0");
testBook6.setTitle(testTitle6);
testBook6.setAuthor(testAuthor6);
testBook6.setISBN(testISBN6);
assertEquals("Title: Moby Dick, Author: Mark Twain, ISBN: 000-00-000-0000-0", testBook6.toString());
}


I receive an error:

org.junit.ComparisonFailure: expected:<[Title: Moby Dick, Author: Mark Twain, ISBN: 000-00-000-0000-0]> but was:<[book.application.Book@48533e64]>
at org.junit.Assert.assertEquals(Assert.java:115)
at org.junit.Assert.assertEquals(Assert.java:144)
at book.application.BookTest.testToString(BookTest.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)


and when I try to run the code in my scrapbook:

Book testBook = new Book();
ISBN testISBN = new ISBN("ISBN: 000-00-000-0000-0");
Title testTitle = new Title("Title: Moby Dick, ");
Author testAuthor = new Author("Author: Mark Twain, ");
Date dNow = new Date( );
SimpleDateFormat ft = new SimpleDateFormat ("MMMM.dd.yyyy");
Price testPrice = new Price(2.25);
Blob testBlob = new Blob("Blah, Blah, Blah");

testBook.setISBN(testISBN);
testBook.setTitle(testTitle);
testBook.setAuthor(testAuthor);
testBook.setPrice(testPrice);
testBook.setBlob(testBlob);

System.out.println(testBook.toString());


to see what's going on, I can only get a return of "book.application.Book@1794d431", with numbers (such as 1794d431) that change randomly every time I run it. All tests pass for every class that "Book" gets and sets from, and no errors are marked. This is only my second Java project, so I am quite new to this; however, I seem to have hit a wall and could certainly use some help!

Thanks in advance!

package book.application;

import java.time.LocalDate;

public class Book {

//fields
private ISBN ISBN;
private Title Title;
private Author Author;
private LocalDate publishDate;
private Price Price;
private Blob Blob;




//getters and setters
public LocalDate getPublishDate() {
return publishDate;
}
public void setPublishDate(LocalDate publishDate) {
this.publishDate = publishDate;
}
public ISBN getISBN() {
return ISBN;
}
public void setISBN(ISBN ISBN) {
this.ISBN = ISBN;
}
public Title getTitle() {
return Title;
}
public void setTitle(Title Title) {
this.Title = Title;
}
public Author getAuthor() {
return Author;
}
public void setAuthor(Author Author) {
this.Author = Author;
}
public Price getPrice() {
return Price;
}
public void setPrice(Price Price) {
this.Price = Price;
}
public Blob getBlob() {
return Blob;
}
public void setBlob(Blob Blob) {
this.Blob = Blob;
}

@Override
public String toString() {
return "Title: " + this.getTitle().getTitle() + ", Author: " + this.getAuthor().getAuthor() + ", ISBN: " + this.getISBN().getISBN() + ", Published on: " + LocalDate.now() + ", costing: $" + this.getPrice().getPrice();
}

}

Answer

You need to override the toString method on your Book class. Currently it is using the default toString() functionality, which returns the object type and hash code.

Here is what your method could look like:

@Override
public String toString() { 
    return "Title: '" + this.title + "', Author: '" + this.author + "', ISBN: '" + this.isbn + "'";
} 

If you're not clear what this means, check out the API for the Object class. In Java, all classes extend Object, so you can access and override (replace) many methods from this class. ToString is one such method, and the default behaviour of this method is not what you would expect, so it is very common to override toString() when creating a new class in Java. Another method you might want to look at is equals().