Wednesday, November 25, 2009

Appendix�D.� ANSWERS TO EXERCISES









































Prev don't be afraid of buying books Next






























Appendix D. ANSWERS TO EXERCISES



This appendix contains answers to the exercises
in the book, with pointers back to where the exercise appeared.

































1.

Refactor TestMovie to use a single
Constructor Method that we just added to Movie.



Answer
1:



public class TestMovie extends TestCase {
private Movie starWars = null;


protected void setUp() {
starWars = new Movie("Star Wars", null, -1);
}

public void testMovieName() {
assertEquals("starWars should have name \"Star Wars\".",
"Star Wars",
starWars.getName());
}
public void testNullName() {
String nullString = null;
try {
new Movie(nullString, null,
-
1);
fail("null name should have thrown IllegalArgumentException.");
} catch (IllegalArgumentException ex) {
}
}

public void testEmptyName() {
try {
new Movie("", null, -1);
fail("empty name should have thrown IllegalArgumentException.");
} catch (IllegalArgumentException ex) {
}
}
public void testToString() {
assertEquals("starWars should have toString of \"Star Wars\".",
"Star Wars",
starWars.toString());
}

public void testEquals() {
final Movie a = new Movie("Star Wars", null,
-
1);
final Movie b = new Movie("Star Wars", null,
-
1);
final Movie c = new Movie("Star Trek", null,
-
1);
final Movie d = new Movie("Star Wars", null,
-
1) {
};
new EqualsTester(a, b, c, d);
}

public void testRenaming() {
String newName = "Star Trek";
Movie aMovie = new Movie("Star Wars", null,
-
1);
aMovie.rename(newName);
assertEquals("Renaming should change the name.",
newName,
aMovie.getName());
}

public void testNullRename() {
Movie aMovie = new Movie("Star Wars", null,
-
1);
try {
aMovie.rename(null);
fail("null rename should have thrown IllegalArgumentException.");
} catch (IllegalArgumentException ex) {
}
}

public void testEmptyRename() {
Movie aMovie = new Movie("Star Wars", null,
-
1);
try {
aMovie.rename("");
fail("empty rename should have thrown IllegalArgumentException.");
} catch (IllegalArgumentException ex) {
}
}

public void testCopyConstructor() {
Movie copyOfStarWars = new Movie(starWars);
assertNotSame("A copy should not be the same as the original.",
starWars,
copyOfStarWars);
assertEquals("A copy should be equal to the original.",
starWars,
copyOfStarWars);
}
public void testUnRated() {
assertFalse("starWars should be unrated.", starWars.hasRating());
}

public void testRatedMovie() throws UnratedException {
Movie fotr = new Movie("Fellowship of the Ring", null, 5);
assertTrue("fotr should be rated", fotr.hasRating());
assertEquals("fotr should be rated at 5.", 5, fotr.getRating());
}

public void testUnratedException() {
try {
starWars.getRating();
fail("getRating on an unrated Movie should throw UnratedException.");
} catch (UnratedException ex) {
assertEquals("UnratedException should identify the movie.",
starWars.getName(),
ex.getMessage());
}
}

public void testUncategorized() {
assertEquals("starWars should be uncategorized.",
"Uncategorized",
starWars.getCategory());
}

public void testScienceFiction() {
Movie alien = new Movie("Alien", "Science Fiction",
-
1);
assertEquals("alien should be Science Fiction.",
"Science Fiction",
alien.getCategory());
}

public static void main(String[ ] args) {
junit.textui.TestRunner.run(TestMovie.class);
}
}






2.

Refactor the tests again, this time removing the
unneeded Movie creation.



Answer
2:



public class TestMovie extends TestCase {
private Movie starWars = null;

protected void setUp() {
starWars = new Movie("Star Wars", null, -1);
}
public void testMovieName() {
assertEquals("starWars should have name \"Star Wars\".",
"Star Wars",
starWars.getName());
}

public void testNullName() {
String nullString = null;
try {
new Movie(nullString, null,
-
1);
fail("null name should have thrown IllegalArgumentException.");
} catch (IllegalArgumentException ex) {
}
}

public void testEmptyName() {
try {
new Movie("", null,
-
1);
fail("empty name should have thrown IllegalArgumentException.");
} catch (IllegalArgumentException ex) {
}
}

public void testToString() {
assertEquals("starWars should have toString of \"Star Wars\".",
"Star Wars",
starWars.toString());
}

public void testEquals() {
final Movie a = new Movie("Star Wars", null,
-
1);
final Movie b = new Movie("Star Wars", null,
-
1);
final Movie c = new Movie("Star Trek", null,
-
1);
final Movie d = new Movie("Star Wars", null,
-
1) {
};
new EqualsTester(a, b, c, d);
}

public void testRenaming() {
String newName = "Star Trek";
starWars.rename(newName);
assertEquals("Renaming should change the name.",
newName,
starWars.getName());
}

public void testNullRename() {
try {
starWars.rename(null);
fail("null rename should have thrown IllegalArgumentException.");
} catch (IllegalArgumentException ex) {
}
}
public void testEmptyRename() {
try {
starWars.rename("");
fail("empty rename should have thrown IllegalArgumentException.");
} catch (IllegalArgumentException ex) {
}
}

public void testCopyConstructor() {
Movie copyOfStarWars = new Movie(starWars);
assertNotSame("A copy should not be the same as the original.",
starWars,
copyOfStarWars);
assertEquals("A copy should be equal to the original.",
starWars,
copyOfStarWars);
}

public void testUnRated() {
assertFalse("starWars should be unrated.", starWars.hasRating());
}

public void testRatedMovie() throws UnratedException {
Movie fotr = new Movie("Fellowship of the Ring", null, 5);
assertTrue("fotr should be rated", fotr.hasRating());
assertEquals("fotr should be rated at 5.", 5, fotr.getRating());
}

public void testUnratedException() {
try {
starWars.getRating();
fail("getRating on an unrated Movie should throw UnratedException.");
} catch (UnratedException ex) {
assertEquals("UnratedException should identify the movie.",
starWars.getName(),
ex.getMessage());
}
}

public void testUncategorized() {
assertEquals("starWars should be uncategorized.",
"Uncategorized",
starWars.getCategory());
}

public void testScienceFiction() {
Movie alien = new Movie("Alien", "Science Fiction",
-
1);
assertEquals("alien should be Science Fiction.",
"Science Fiction",
alien.getCategory());
}
public static void main(String[ ] args) {
junit.textui.TestRunner.run(TestMovie.class);
}
}































3.

The customer identified these categories: Science Fiction, Horror, Comedy, Western,
Drama, Fantasy, Kids, Adult, Mystery, Thriller
. Add these to
Category.



Answer
3:



public class Category {
private String name=null;

private Category(String categoryName) {
name = categoryName;
}
public static final Category UNCATEGORIZED = new Category("Uncategorized");
public static final Category SCIFI = new Category("Science Fiction");
public static final Category HORROR = new Category("Horror");
public static final Category COMEDY = new Category("Comedy");
public static final Category WESTERN = new Category("Western");
public static final Category DRAMA = new Category("Drama");
public static final Category FANTASY = new Category("Fantasy");
public static final Category KIDS = new Category("Kids");
public static final Category ADULT = new Category("Adult");
public static final Category MYSTERY = new Category("Mystery");
public static final Category THRILLER = new Category("Thriller");
}













































4.

Extend setCategoryField() to make
testSelecting() pass.



Answer
4:



public void select(int i) {
if (i == -1) {
selectedMovie = null;
} else {
selectedMovie = movies.getMovie(i);
view.setNameField(selectedMovie.getName());
view.setCategoryField(selectedMovie.getCategory());

try {
view.setRatingField(selectedMovie.getRating() + 1);
} catch (UnratedException e) {
view.setRatingField(0);
}
}
}






5.

What problem does this cause? Why? Fix it.



Answer
5:


It breaks testUpdating(),
testUpdatingWithSameName(),and
testDuplicateCausingUpdate because they don't expect the
calls to setCategoryField().



Here are the updated methods. We just need to
add expectations for the calls to setCategoryField():




public void testUpdating() {
Vector newMovies = new Vector();
newMovies.add(starWars);
newMovies.add(new Movie("Star Trek I", Category.SCIFI, 5));
newMovies.add(stargate);
newMovies.add(theShining);

mockView.setMovies(movies);
control.setVoidCallable(1);

mockView.setNameField("Star Trek");
control.setVoidCallable(1);
mockView.setRatingField(4);
control.setVoidCallable();
mockView.setCategoryField(Category.SCIFI);
control.setVoidCallable(1);

mockView.getNameField();
control.setReturnValue("Star Trek I",1);
mockView.getRatingField();
control.setReturnValue(6, 1);

mockView.setMovies(newMovies);
control.setVoidCallable(1);

control.activate();

MovieListEditor editor = new MovieListEditor(movieList,mockView);
editor.select(1);
editor.update();

control.verify();
}

public void testUpdatingWithSameName() {
Vector newMovies = new Vector();
newMovies.add(starWars);
newMovies.add(new Movie("Star Trek",Category.SCIFI, 5));
newMovies.add(stargate);
newMovies.add(theShining);

mockView.setMovies(movies);
control.setVoidCallable(1);
mockView.setNameField("Star Trek");
control.setVoidCallable(1);
mockView.setRatingField(4);
control.setVoidCallable();
mockView.setCategoryField(Category.SCIFI);
control.setVoidCallable(1);

mockView.getNameField();
control.setReturnValue("Star Trek", 1);
mockView.getRatingField();
control.setReturnValue(6, 1);

mockView.setMovies(newMovies);
control.setVoidCallable(1);

control.activate();

MovieListEditor editor = new MovieListEditor(movieList, mockView);
editor.select(1);
editor.update();

control.verify();
}
public void testDuplicateCausingUpdate() {
mockView.setMovies(movies);
control.setVoidCallable(1);

mockView.setNameField("Star Trek");
control.setVoidCallable(1);
mockView.setRatingField(0);
control.setDefaultVoidCallable();
mockView.setCategoryField(Category.SCIFI);
control.setVoidCallable(1);

mockView.getNameField();
control.setReturnValue("Star Wars", 1);

mockView.duplicateException("Star Wars");
control.setVoidCallable(1);

control.activate();

MovieListEditor editor = new MovieListEditor(movieList, mockView);
editor.select(1);
editor.update();

control.verify();
}































6.

We used the toString() method to get
the value for the category field, as well as the value from the
expected Category to compare against the field contents.
What's the problem that we have with the system in its current
state? (Hint: look at Category.) Fix it.



Answer
6:


We haven't defined Category.toString()
so it just uses the default from Object. This gives a consistent
result, and so our test passes. However, it's not human readable.
To fix it we need to add toString() to
Category:




public String toString() {
return name;
}































7.

Make the required changes to Movie and
TestMovieListEditor.



Answer
7:


Add a mutator for category tp
Movie:




public void setCategory(Category aCategory) {
category = aCategory;
}






In TestMovieListEditor, add an
expectation for the call to getCategoryField() in
testUpdatingWithSameName():




public void testUpdatingWithSameName() {
Vector newMovies = new Vector();
newMovies.add(starWars);
newMovies.add(new Movie("Star Trek", Category.SCIFI, 5));
newMovies.add(stargate);
newMovies.add(theShining);

mockView.setMovies(movies);
control.setVoidCallable(1);

mockView.setNameField("Star Trek");
control.setVoidCallable(1);
mockView.setRatingField(4);
control.setVoidCallable();
mockView.setCategoryField(Category.SCIFI);
control.setVoidCallable(1);

mockView.getNameField();
control.setReturnValue("Star Trek", 1);
mockView.getRatingField();
control.setReturnValue(6, 1);
mockView.getCategoryField(); // this line added
control.setReturnValue(Category.SCIFI, 1); // this line added
mockView.setMovies(newMovies);
control.setVoidCallable(1);

control.activate();

MovieListEditor editor = new MovieListEditor(movieList, mockView);
editor.select(1);
editor.update();

control.verify();
}































8.

Write a toString() method for
MovieList.



Answer
8:



public String toString() {
StringBuffer buf = new StringBuffer("[");
Iterator movieIterator = movies.iterator();
boolean first = true;

while (movieIterator.hasNext()) {
Movie aMovie = (Movie) movieIterator.next();
if (!first) {
buf.append('');
}
first = false;
buf.append('"');
buf.append(aMovie.getName());
buf.append('"');
}
buf.append(']');
return buf.toString();
}































9.

Write an equals() method for
MovieList. Start by adding a test to
TestMovieList-WithPopulatedList.



Answer
9:


First, the test:




public void testEquals() throws DuplicateMovieException {
MovieListequalList = new MovieList();
equalList.add(starWars);
equalList.add(starTrek);
equalList.add(stargate);

MovieList unequalList = new MovieList();
unequalList.add(starWars);
unequalList.add(stargate);
new EqualsTester(movieList, equalList, unequalList, null);
}






Then the equals() method (be sure you
didn't forget hashCode()):




public boolean equals(Object o) {
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != this.getClass()) return false;

MovieList aMovieList=(MovieList)o;
return movies.equals(aMovieList.movies);

}

public int hashCode() {
return movies.hashCode();
}































10.

Extend the fixture to support this test.



Answer
10:



//...
private MovieList scifiList = null;
private MovieList thrillerList = null;
private MovieList horrorList = null;

protected void setUp() throws Exception {
//. . .
scifiList = new MovieList();
scifiList.add(starWars);
scifiList.add(starTrek);
scifiList.add(stargate);

thrillerList = new MovieList();
thrillerList.add(redOctober);
thrillerList.add(congo);

horrorList = new MovieList();
horrorList.add(theShining);
horrorList.add(carrie);
}































11.

Make the required updates to add
filteredMovies.



Answer
11:



public class MovieListEditor {
private MovieList filteredMovies;

public MovieListEditor(MovieList movieList, MovieListEditorView aView) {
movies = movieList;
filteredMovies=movieList;
view = aView;
view.setEditor(this);
updateMovieList();
}

private void updateMovieList() {
view.setMovies(new Vector(filteredMovies.getMovies()));
}
}































12.

Extract the fixture code from the two tests into
setUp().



Answer
12:



public class TestMovieListWriter extends TestCase {
StringWriter destination = null;
MovieList movieList = null;

protected void setUp() {
destination = new StringWriter();
movieList=newMovieList();
}
public void testWritingEmptyList() throws Exception {
movieList.writeTo(destination);
assertEquals("Writing an empty list should produce nothing.",
"",
destination.toString());
}

public void testWritingOneMovie() throws Exception {
String starWarsOutput = "Star Wars|Science Fiction|4\n";
Movie starWars = new Movie("Star Wars", Category.SCIFI, 4);
movieList.add(starWars);
movieList.writeTo(destination);
assertEquals("Wrong output from writing a single movie list.",
starWarsOutput,
destination.toString());
}

public static void main(String[ ] args) {
junit.textui.TestRunner.run(TestMovieListWriter.class);
}
}































13.

Add the method stubs and declarations we need in
order to get the test compiling.



Answer
13:


In MovieListEditor:




public void saveAs() {
}






In MovieListEditorView:




File getFile(String string);






And in SwingMovieListEditorView:




public File getFile(String pattern) {
return null;
}































14.

Make the required change to
TestMovieListEditorFileOperations.testSaving().



Answer
14:



public void testSaving() throws Exception {
mockView.setMovies(movies);
control.setVoidCallable(1);
mockView.getFile();
control.setReturnValue(outputFile, 1);
control.activate();

MovieListEditor editor = new MovieListEditor(movieList, mockView);
assertTrue("Editor should have saved", editor.saveAs());
FileAssert.assertSize("Save As-ed file has wrong size.",
expected.length(),
outputFile);
FileAssert.assertEquals("Save As-ed file has wrong contents ",
expected,
outputFile);
control.verify();
}































15.

Fix the add() related tests in
TestMovieListEditor.



Answer
15:



public void testAdding() throws DuplicateMovieException {
String LOST IN SPACE = "Lost In Space";
Movie lostInSpace = new Movie(LOST IN SPACE, Category.SCIFI, 3);
Vector moviesWithAddition = new Vector(movies);
moviesWithAddition.add(lostInSpace);


mockView.setMovies(movies);
control.setVoidCallable(1);
mockView.getNameField();
control.setReturnValue(LOST IN SPACE, 1);
mockView.getCategoryField();
control.setReturnValue(Category.SCIFI, 1);
mockView.getRatingField();
control.setReturnValue(3, 1);
mockView.setMovies(moviesWithAddition);
control.setVoidCallable(1);
control.activate();

MovieListEditor editor = new MovieListEditor(movieList, mockView);
editor.add();

control.verify();
}
public void testDuplicateCausingAdd() {
mockView.setMovies(movies);
control.setVoidCallable(1);

mockView.getNameField();
control.setReturnValue("Star Wars", 1);
mockView.getCategoryField();
control.setReturnValue(Category.SCIFI, 1);
mockView.getRatingField();
control.setReturnValue(5, 1);

mockView.duplicateException("Star Wars");
control.setVoidCallable(1);
control.activate();

MovieListEditor editor = new MovieListEditor(movieList, mockView);
editor.add();

control.verify();
}































16.

Fix up the add related tests in
TestSwingMovieListEditorView.



Answer
16:



public void testAdding() {
String LOST IN SPACE = "Lost In Space";
Movie lostInSpace = new Movie(LOST IN SPACE, Category.SCIFI, 3);
movies.add(lostInSpace);

JTextFieldOperator newMovieField =
new JTextFieldOperator(mainWindow,
new NameBasedChooser("name"));
newMovieField.enterText(LOST IN SPACE);

JComboBoxOperator ratingCombo =
new JComboBoxOperator(mainWindow,
new NameBasedChooser("rating"));
ratingCombo.setSelectedIndex(4);

JComboBoxOperator categoryCombo =
new JComboBoxOperator(mainWindow,
new NameBasedChooser("category"));
categoryCombo.setSelectedIndex(1);

JButtonOperator addButton =
new JButtonOperator(mainWindow,
new NameBasedChooser("add"));
addButton.doClick();

JListOperator movieList =
new JListOperator(mainWindow,
new NameBasedChooser("movieList"));
ListModel listModel = movieList.getModel();
assertEquals("Movie list is the wrong size", movies.size(),
listModel.getSize());

for (int i = 0; i
<
movies.size(); i++) {
assertEquals("Movie list contains bad movie at index " + i, movies.get(i),
listModel.getElementAt(i));
}
}

public void testDuplicateCausingAdd() {
JTextFieldOperator newMovieField =
new JTextFieldOperator(mainWindow,
new NameBasedChooser("name"));
newMovieField.enterText(starWars.getName());
JComboBoxOperator ratingCombo =
new JComboBoxOperator(mainWindow,
new NameBasedChooser("rating"));
ratingCombo.setSelectedIndex(4);

JComboBoxOperator categoryCombo =
new JComboBoxOperator(mainWindow,
new NameBasedChooser("category"));
categoryCombo.setSelectedIndex(1);

JButtonOperator addButton =
new JButtonOperator(mainWindow,
new NameBasedChooser("add"));
addButton.pushNoBlock();
checkDuplicateExceptionDialog();
JListOperator movieList =
new JListOperator(mainWindow,
new NameBasedChooser("movieList"));
checkListIsUnchanged(movieList);
}































17.

Do the split:
TestMovieListEditorFileOperations into
TestMovieListEditorSaving and
TestMovieListEditorLoading.



Answer
17:










  1. Rename
    TestMovieListEditorFileOperations to
    TestMovieListEditorSaving.











  2. Create TestMovieListEditorLoading,
    copying loading related parts of
    TestMovieListEditorSaving:












public class TestMovieListEditorLoading
extends CommonTestMovieListEditor {
private Vector emptyMovies;
privateFile inputFile;

protected void setUp() throws Exception {
super.setUp();
inputFile = File.createTempFile("testSaving", "dat");
inputFile.deleteOnExit();
emptyMovies = new Vector();
}

public void testLoading() throws Exception {
mockView.setMovies(emptyMovies);
control.setVoidCallable(1);
mockView.getFileToLoad();
control.setReturnValue(inputFile, 1);

mockView.setMovies(movies);
control.setVoidCallable(1);
control.activate();

MovieListEditor editor = new MovieListEditor(new MovieList(),
mockView);
assertTrue("Editor should have loaded.", editor.load());
control.verify();
}

public static void main(String[ ] args) {
junit.textui.TestRunner.run(TestMovieListEditorLoading.class);
}
}































18.

In looking at adding another test to
TestSwingMovieListEditorFileOperations, we notice that we
have some code debt. The Rule of
Three
has kicked in. This is the third test, and as we think
about it we see that there are a few lines of code duplicated in
each test. Time to refactor. What do we need to do?



Answer
18:


Each test begins with these three lines that
need to be moved to the end of setUp() and removed from
the two existing tests:




menubar = new JMenuBarOperator(mainWindow);
fileMenu= new JMenuOperator(menubar, "File");
fileMenu.push();































19.

What does the fixture look like?



Answer
19:



public class TestMovieListSortingByName extends TestCase {
private MovieList sortedList = null;
private MovieNameComparator nameComparator = null;
private Vector sortedMovies = null;
private MovieList emptyList = null;

protected void setUp() throws Exception {
emptyList = new MovieList();
sortedMovies = new Vector();

sortedMovies.add(new Movie("A", Category.SCIFI, 5));
sortedMovies.add(new Movie("B", Category.SCIFI, 4));
sortedMovies.add(new Movie("C", Category.SCIFI, 3));
sortedMovies.add(new Movie("D", Category.SCIFI, 2));
sortedMovies.add(new Movie("E", Category.SCIFI, 1));
sortedMovies.add(new Movie("F", Category.SCIFI, 0));
sortedMovies.add(new Movie("G", Category.SCIFI,
-
1));

sortedList=newMovieList();
Iterator i = sortedMovies.iterator();
while (i.hasNext()) {
sortedList.add((Movie) i.next());
}
nameComparator = new MovieNameComparator();
}
//. . .
}































20.

Do the extraction of the fixture.



Answer
20:



public class TestMovieRatings extends TestCase {
private Movie starTrek = null;

protected void setUp() throws Exception {
starTrek = new Movie("Star Trek", Category.SCIFI);
}
public void testUnratedConstructor() {
try {
starTrek.getRating();
fail("Getting rating of an unrated Movie should throw UnratedMovieException");
} catch (UnratedException ex) {
}
}
public void testAddingOneRating() throws Exception {
starTrek.addRating(3);
assertEquals("Bad average rating of 1.", 3, starTrek.getRating());
}
public static void main(String[ ] args) {
junit.textui.TestRunner.run(TestMovieRatings.class);
}
}































21.

What is the problem, and how do we fix it?



Answer
21:


The expected saved data strings don't include a
rating count value.



They need to be updated to:




public class TestMovieListEditorSaving extends CommonTestMovieListEditor {
protected void setUp() throws Exception {
super.setUp();
expected = "Star Wars|Science Fiction|5|1\n" +
"Star Trek|Science Fiction|3|1\n" +
"Stargate|Science Fiction|0|0\n" +
"The Shining|Horror|2|1\n";
extendedExpected = expected + "The Fellowship of The Ring|Fantasy|5|1\n";
}
//...
}

public class TestSwingMovieListEditorFileOperations extends TestCase {
protected void setUp() throws Exception {
//. . .
savedText = "Star Wars|Science Fiction|5|1\n" +
"Star Trek|Science Fiction|3|1\n" +
"Stargate|Science Fiction|0|0\n";
extendedSavedText = savedText + "The Shining|Horror|2|1\n";
}
}













































22.

Convert TestMovieListEditorSaving as
required.



Answer
22:



public class TestMovieListEditorSaving extends XMLTestCase {
protected MockControl control = null;
protected MovieListEditorView mockView = null;
protected Vector movies = null;
protected Movie starWars = null;
protected Movie starTrek = null;
protected Movie stargate = null;
protected Movie theShining = null;
protected MovieList movieList = null;
private String expectedPrefix;
private String expected;
private File outputFile;
private Movie fotr;
private String extendedExpected;
private Vector extendedMovies;

public TestMovieListEditorSaving(String name) {
super(name);
}

protected void setUp() throws Exception {
String parser = "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl";
XMLUnit.setControlParser(parser);
XMLUnit.setTestParser(parser);

starWars = new Movie("Star Wars", Category.SCIFI, 5);
starTrek = new Movie("Star Trek", Category.SCIFI, 3);
stargate = new Movie("Stargate", Category.SCIFI,
-
1);
theShining = new Movie("The Shining", Category.HORROR, 2);

movies =newVector();
movies.add(starWars);
movies.add(starTrek);
movies.add(stargate);
movies.add(theShining);

movieList = newMovieList();
movieList.add(starWars);
movieList.add(starTrek);
movieList.add(stargate);
movieList.add(theShining);

expectedPrefix = "<movielist>" +
"<movie name=\"Star Wars\" " +
"category=\"Science Fiction\">" +
"<ratings>" +
"<rating value=\"5\" " +
"source=\"Anonymous\" />" +
"</ratings>" +
"</movie>" +
"<movie name=\"Star Trek\" " +
"category=\"Science Fiction\">" +
"<ratings>" +
"<rating value=\"3\" " +
"source=\"Anonymous\" />" +
"</ratings>" +
"</movie>" +
"<movie name=\"Stargate\" " +
"category=\"Science Fiction\">" +
"<ratings></ratings>" +
"</movie>" +
"<movie name=\"The Shining\" " +
"category=\"Horror\">" +
"<ratings>" +
"<rating value=\"2\" " +
"source=\"Anonymous\" />" +
"</ratings>" +
"</movie>";
expected = expectedPrefix + "</movielist>";

fotr = new Movie("The Fellowship of The Ring", Category.FANTASY, 5);
extendedExpected = expectedPrefix +
"<movie name=\"The Fellowship of The Ring\" " +
"category=\"Fantasy\">" +
"<ratings>" =
"<rating value=\"5\" " +
"source=\"Anonymous\" />" +
"</ratings>" +
"</movie></movielist>";

extendedMovies = new Vector(movies);
extendedMovies.add(fotr);

outputFile = File.createTempFile("testSaving", ".dat");
outputFile.deleteOnExit();

control = EasyMock.controlFor(MovieListEditorView.class);
mockView = (MovieListEditorView)control.getMock();
mockView.setEditor(null);
control.setDefaultVoidCallable();
}

public void testSaving() throws Exception {
mockView.setMovies(movies);
control.setVoidCallable(1);
mockView.getFileToSave();
control.setReturnValue(outputFile, 1);

mockView.getNameField();
control.setReturnValue(fotr.getName(), 1);
mockView.getCategoryField();
control.setReturnValue(Category.FANTASY, 1);
mockView.getRatingField();
control.setReturnValue(fotr.getRating() + 1, 1);
mockView.setMovies(extendedMovies);
control.setVoidCallable(1);
control.activate();

MovieListEditor editor = new MovieListEditor(movieList, mockView);
assertTrue("Editor should have saved", editor.saveAs());
assertXMLEqual("Save As-ed file has wrong contents ",
expected,
contentsOf(outputFile));

editor.add();
assertTrue("Editor should have resaved", editor.save());
assertXMLEqual("Saved file has bad contents.",
extendedExpected,
contentsOf(outputFile));
control.verify();
}

private String contentsOf(File aFile) throws IOException {
FileInputStream fstream = new FileInputStream(aFile);
int size = fstream.available();
byte[ ] buffer = new byte[size];
fstream.read(buffer);
return new String(buffer);
}

public void testCancelledSaving() throws Exception {
mockView.setMovies(movies);
control.setVoidCallable(1);
mockView.getFileToSave();
control.setReturnValue(null, 1);
control.activate();

MovieListEditor editor = new MovieListEditor(movieList, mockView);
assertFalse("Editor should not have saved.", editor.saveAs());
control.verify();
}

public static void main(String[ ] args) {
junit.textui.TestRunner.run(TestMovieListEditorSaving.class);
}
}






23.

Update MovieListEditor.save() to make
it work.



Answer
23:



public boolean save() throws IOException {
if (outputFile == null) {
return false;
}
FileWriter writer = new FileWriter(outputFile);
new XMLMovieListWriter(writer).write(movies);
writer.close();
return true;
}


























































Amazon






No comments: