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: |
Rename TestMovieListEditorFileOperations to TestMovieListEditorSaving.
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; }
|
|
No comments:
Post a Comment