Java/Development Class/Unit Test
Содержание
- 1 Assert equals: int
- 2 Assert equals: Long
- 3 Assertion tool for debugging
- 4 Before annotation
- 5 Debug frame
- 6 Demonstration of Design by Contract (DBC) combined with white-box unit testing
- 7 Error Handler
- 8 JUnit assertEquals: Float With Delta
- 9 JUnit assertEquals With Message
- 10 JUnit assertTrue
- 11 JUnit assertTrue: ObjectArray
- 12 JUnit BeforeClass
- 13 JUnit Extends TestCase
- 14 JUnit Ignore
- 15 JUnit Test Case With Expected Exception
- 16 JUnit Test Setup
- 17 Random data for test
- 18 Redirect or reassign some standard descriptors
- 19 Set JUnit Test case fail information
- 20 Simple Debugging
- 21 Simple test with JUnit
- 22 Simple use of JUnit to test ArrayList
- 23 Simple utility for testing program output
- 24 Testing class Class
- 25 Utilities for debugging
Assert equals: int
<source lang="java">
import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import junit.framework.JUnit4TestAdapter; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; public class MainClass{
public static void main (String... args) { junit.textui.TestRunner.run (suite()); } public static junit.framework.Test suite() { return new JUnit4TestAdapter(MainClass.class); } @Test public void testCopy() { assertEquals(12, 12); assertEquals(12L, 12L); assertEquals(new Long(12), new Long(12)); }
}
</source>
Assert equals: Long
<source lang="java">
import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import junit.framework.JUnit4TestAdapter; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; public class MainClass{
public static void main (String... args) { junit.textui.TestRunner.run (suite()); } public static junit.framework.Test suite() { return new JUnit4TestAdapter(MainClass.class); } @Test public void testCopy() { assertEquals(12, 12); assertEquals(12L, 12L); assertEquals(new Long(12), new Long(12)); }
}
</source>
Assertion tool for debugging
<source lang="java">
//: com:bruceeckel:tools:debug:Assert.java // Assertion tool for debugging. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt.
public class Assert {
private static void perr(String msg) { System.err.println(msg); } public static final void is_true(boolean exp) { if(!exp) perr("Assertion failed"); } public static final void is_false(boolean exp) { if(exp) perr("Assertion failed"); } public static final void is_true(boolean exp, String msg) { if(!exp) perr("Assertion failed: " + msg); } public static final void is_false(boolean exp, String msg) { if(exp) perr("Assertion failed: " + msg); }
} ///:~
</source>
Before annotation
<source lang="java">
/* run:
[java] JVM args ignored when same JVM is used. [java] @BeforeClass: set up onece [java] .@Before: set up [java] Time: 0.015 [java] OK (1 test)
- /
import java.util.ArrayList; import java.util.List;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import junit.framework.JUnit4TestAdapter; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; /**
* Some simple tests. * */
public class MainClass{
public static void main (String... args) { junit.textui.TestRunner.run (suite()); } @BeforeClass public static void setUpOnce() { System.out.println("@BeforeClass: set up onece"); } @Before public void setUp() { System.out.println("@Before: set up "); } public static junit.framework.Test suite() { return new JUnit4TestAdapter(MainClass.class); } @Test public void testCopy() { assertTrue(1 == 1); }
}
</source>
Debug frame
<source lang="java">
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; public class DebugWinTest extends JFrame implements ActionListener {
private JButton aButton = new JButton("button"); private DebugWin dw = new DebugWin(); public DebugWinTest() { setTitle("DebugWinTest"); setSize(100, 100); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); JPanel pane = new JPanel(); pane.add(aButton); aButton.addActionListener(this); getContentPane().add(pane); } public void actionPerformed(ActionEvent evt) { dw.print("Event = " + evt); } public static void main(String[] args) { JFrame f = new DebugWinTest(); f.show(); } class DebugWin extends JFrame { private JTextArea output = new JTextArea(); public void print(Object ob) { output.append("\n" + ob); } public DebugWin() { setTitle("DebugWin"); output.setEditable(false); output.setText("[DebugWin]"); getContentPane().add(new JScrollPane(output), "Center"); setSize(300, 200); setLocation(200, 200); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { setVisible(false); } }); show(); } }
}
</source>
Demonstration of Design by Contract (DBC) combined with white-box unit testing
<source lang="java">
// : c15:JavaQueue.java // Demonstration of Design by Contract (DBC) combined // with white-box unit testing. // {Depends: junit.jar} // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. import junit.framework.*; import java.util.*; public class JavaQueue {
private Object[] data; private int in = 0, // Next available storage space out = 0; // Next gettable object // Has it wrapped around the circular queue? private boolean wrapped = false; public static class QueueException extends RuntimeException { public QueueException(String why) { super(why); } }
public JavaQueue(int size) {
data = new Object[size]; assert invariant(); // Must be true after construction } public boolean empty() { return !wrapped && in == out; } public boolean full() { return wrapped && in == out; }
public void put(Object item) {
precondition(item != null, "put() null item"); precondition(!full(), "put() into full Queue"); assert invariant(); data[in++] = item; if(in >= data.length) { in = 0; wrapped = true; } assert invariant(); }public Object get() { precondition(!empty(), "get() from empty Queue"); assert invariant(); Object returnVal = data[out]; data[out] = null; out++; if(out >= data.length) { out = 0; wrapped = false; } assert postcondition( returnVal != null, "Null item in Queue"); assert invariant(); return returnVal; } // Design-by-contract support methods: private static void precondition(boolean cond, String msg) { if (!cond) throw new QueueException(msg); } private static boolean postcondition(boolean cond, String msg) { if (!cond) throw new QueueException(msg); return true; } private boolean invariant() { // Guarantee that no null values are in the // region of "data" that holds objects: for (int i = out; i != in; i = (i + 1) % data.length) if (data[i] == null) throw new QueueException("null in queue"); // Guarantee that only null values are outside the // region of "data" that holds objects: if (full()) return true; for (int i = in; i != out; i = (i + 1) % data.length) if (data[i] != null) throw new QueueException("non-null outside of queue range: " + dump()); return true; } private String dump() { return "in = " + in + ", out = " + out + ", full() = " + full() + ", empty() = " + empty() + ", queue = " + Arrays.asList(data); } // JUnit testing. // As an inner class, this has access to privates: public static class WhiteBoxTest extends TestCase { private JavaQueue queue = new JavaQueue(10); private int i = 0; public WhiteBoxTest(String name) { super(name); while (i < 5) // Preload with some data queue.put("" + i++); } // Support methods: private void showFullness() { assertTrue(queue.full()); assertFalse(queue.empty()); // Dump is private, white-box testing allows access: System.out.println(queue.dump()); } private void showEmptiness() { assertFalse(queue.full()); assertTrue(queue.empty()); System.out.println(queue.dump()); } public void testFull() { System.out.println("testFull"); System.out.println(queue.dump()); System.out.println(queue.get()); System.out.println(queue.get()); while (!queue.full()) queue.put("" + i++); String msg = ""; try { queue.put(""); } catch (QueueException e) { msg = e.getMessage(); System.out.println(msg); } assertEquals(msg, "put() into full Queue"); showFullness(); } public void testEmpty() { System.out.println("testEmpty"); while (!queue.empty()) System.out.println(queue.get()); String msg = ""; try { queue.get(); } catch (QueueException e) { msg = e.getMessage(); System.out.println(msg); } assertEquals(msg, "get() from empty Queue"); showEmptiness(); } public void testNullPut() { System.out.println("testNullPut"); String msg = ""; try { queue.put(null); } catch (QueueException e) { msg = e.getMessage(); System.out.println(msg); } assertEquals(msg, "put() null item"); } public void testCircularity() { System.out.println("testCircularity"); while (!queue.full()) queue.put("" + i++); showFullness(); // White-box testing accesses private field: assertTrue(queue.wrapped); while (!queue.empty()) System.out.println(queue.get()); showEmptiness(); while (!queue.full()) queue.put("" + i++); showFullness(); while (!queue.empty()) System.out.println(queue.get()); showEmptiness(); } } public static void main(String[] args) { junit.textui.TestRunner.run(JavaQueue.WhiteBoxTest.class); }
} ///:~
</source>
Error Handler
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; /**
* Contrived program showing how to catch Exceptions that occur on the event * dispatching thread. Define the System property "sun.awt.exception.handler" to * name a class with a method **
* * public void handle(Throwable t) * *. *
* That really is all you have to do to catch GUI Exceptions. But it may change * at any time (hence the name sun.awt...). * * @author Ian Darwin. */ public class ErrorHandlerTest extends JFrame { /** * A fairly banal GUI, just to show interaction. */ ErrorHandlerTest() { super("GUI"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container cp = getContentPane(); JButton bx = new JButton("Throw!"); bx.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { throw new IllegalArgumentException("foo"); } }); cp.add(bx); setBounds(200, 200, 200, 100); } public static void main(String[] args) { // Tell AWT to invoke my Handler. System.setProperty("sun.awt.exception.handler", "ErrorHandler"); // Now create and show the GUI. new ErrorHandlerTest().setVisible(true); } } /** * This class is usable by AWT to handle exceptions. * System.setProperty("sun.awt.exception.handler", "ErrorHandler"); This usage * is documented in the source code up to 1.4Beta for * java.awt.EventDispatchThread. This class exists in all standard * implementations (try "javap java.awt.EventQueueDispatchThread"), but is not * public so there"s no javadoc. NOTE: there is a strong admonition that the * interface WILL be changed in future. * <p> * In real life this could be part of your application, and can do almost * anything. The error handler itself does not need to import awt, awt.event, * swing, or anything else. * * @author Ian Darwin * @version $Id: ErrorHandler.java,v 1.4 2003/08/24 12:31:03 ian Exp $ */ class ErrorHandler extends java.lang.Object { /** * Default constructor must exist (I know it"s the default; this is here in * case somebody adds any other constructor). */ public ErrorHandler() { System.out.println("CONSTRUCTED"); } public void handle(Throwable t) { System.err.println("Hey, I caught it!"); System.err.println(t.toString()); } } </source>
JUnit assertEquals: Float With Delta
<source lang="java">
import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import junit.framework.JUnit4TestAdapter; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; public class MainClass{
public static void main (String... args) { junit.textui.TestRunner.run (suite()); } public static junit.framework.Test suite() { return new JUnit4TestAdapter(MainClass.class); } @Test public void testCopy() { assertEquals("Capacity", 11.991, 11.99, 0.1); }
}
</source>
JUnit assertEquals With Message
<source lang="java">
import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import junit.framework.JUnit4TestAdapter; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; public class MainClass{
public static void main (String... args) { junit.textui.TestRunner.run (suite()); } public static junit.framework.Test suite() { return new JUnit4TestAdapter(MainClass.class); } @Test public void testCopy() { assertEquals("Size", 12, 13); }
}
</source>
JUnit assertTrue
<source lang="java">
/* run:
[java] JVM args ignored when same JVM is used. [java] @BeforeClass: set up onece [java] .@Before: set up [java] Time: 0.015 [java] OK (1 test)
- /
import java.util.ArrayList; import java.util.List;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import junit.framework.JUnit4TestAdapter; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; /**
* Some simple tests. * */
public class MainClass{
public static void main (String... args) { junit.textui.TestRunner.run (suite()); } @BeforeClass public static void setUpOnce() { System.out.println("@BeforeClass: set up onece"); } @Before public void setUp() { System.out.println("@Before: set up "); } public static junit.framework.Test suite() { return new JUnit4TestAdapter(MainClass.class); } @Test public void testCopy() { assertTrue(1 == 1); }
}
</source>
JUnit assertTrue: ObjectArray
<source lang="java">
import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import junit.framework.JUnit4TestAdapter; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; public class MainClass{
public static void main (String... args) { junit.textui.TestRunner.run (suite()); } public static junit.framework.Test suite() { return new JUnit4TestAdapter(MainClass.class); } @Test public void arraysNotEqual() { assertEquals("message", new Object[] {true, true}, new Object[] {true, false}); }
}
</source>
JUnit BeforeClass
<source lang="java">
/* run:
[java] JVM args ignored when same JVM is used. [java] @BeforeClass: set up onece [java] .@Before: set up [java] Time: 0.015 [java] OK (1 test)
- /
import java.util.ArrayList; import java.util.List;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import junit.framework.JUnit4TestAdapter; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; /**
* Some simple tests. * */
public class MainClass{
public static void main (String... args) { junit.textui.TestRunner.run (suite()); } @BeforeClass public static void setUpOnce() { System.out.println("@BeforeClass: set up onece"); } @Before public void setUp() { System.out.println("@Before: set up "); } public static junit.framework.Test suite() { return new JUnit4TestAdapter(MainClass.class); } @Test public void testCopy() { assertTrue(1 == 1); }
}
</source>
JUnit Extends TestCase
<source lang="java">
import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite;
public class MainClass extends TestCase{
public static void main (String[] args) { junit.textui.TestRunner.run (suite()); } public static junit.framework.Test suite() { return new TestSuite(MainClass.class); } public void testAdd() { assertTrue(6 == 6); } public void testDivideByZero() { int zero= 0; int result= 8/zero; } public void testEquals() { assertEquals(12, 12); }
}
</source>
JUnit Ignore
<source lang="java">
import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import junit.framework.JUnit4TestAdapter; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; public class MainClass{
public static void main (String... args) { junit.textui.TestRunner.run (suite()); } public static junit.framework.Test suite() { return new JUnit4TestAdapter(MainClass.class); } @Ignore("not today") @Test public void capacity() { assertTrue(1 == 2); } @Test public void testCopy() { assertEquals("Capacity", 11.991, 11.99, 0.1); }
}
</source>
JUnit Test Case With Expected Exception
<source lang="java">
import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import junit.framework.JUnit4TestAdapter; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; public class MainClass{
public static void main (String... args) { junit.textui.TestRunner.run (suite()); } public static junit.framework.Test suite() { return new JUnit4TestAdapter(MainClass.class); } @Test (expected=IndexOutOfBoundsException.class) public void elementAt() { int[] intArray = new int[10]; int i = intArray[20]; // Should throw IndexOutOfBoundsException }
}
</source>
JUnit Test Setup
<source lang="java">
import junit.extensions.TestSetup; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; public class MainClass extends TestCase {
public static void main (String... args) { junit.textui.TestRunner.run (suite()); } private static TSP tsp; public MainClass(String method) { super(method); } // This one takes a few hours... public void testLongRunner() { assertEquals(2300, tsp.shortestPath(50)); } public void testShortTest() { assertEquals(140, tsp.shortestPath(5)); } public void testAnotherShortTest() { assertEquals(586, tsp.shortestPath(10)); } public static Test suite() { TestSuite suite = new TestSuite(); // Only include short tests suite.addTest(new MainClass("testShortTest")); suite.addTest(new MainClass("testAnotherShortTest")); TestSetup wrapper = new TestSetup(suite) { protected void setUp() { oneTimeSetUp(); } protected void tearDown() { oneTimeTearDown(); } }; return wrapper; } public static void oneTimeSetUp() { System.out.println("oneTimeSetUp()"); // one-time initialization code goes here... tsp = new TSP(); tsp.loadCities("EasternSeaboard"); } public static void oneTimeTearDown() { // one-time cleanup code goes here... tsp.releaseCities(); }
} class TSP {
public int shortestPath(int numCities) { switch (numCities) { case 50: return 2300; case 5: return 140; case 10: return 586; } return 0; } public void loadCities(String name) { } public void releaseCities() { }
}
</source>
Random data for test
<source lang="java">
/*
* Copyright 2005 Joe Walker * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
import java.util.Random; /**
* @author Joe Walker [joe at getahead dot ltd dot uk] */
public class RandomData {
/** * @param isUS US numbers look different to UK ones * @return A phone number */ public static String getPhoneNumber(boolean isUS) { String phoneNumber; if (isUS) { // US phoneNumber = "+1 (" + random.nextInt(9) + random.nextInt(9) + random.nextInt(9) + ") " + random.nextInt(9) + random.nextInt(9) + random.nextInt(9) + " - " + random.nextInt(9) + random.nextInt(9) + random.nextInt(9) + random.nextInt(9); } else { // UK phoneNumber = "+44 (0) 1" + random.nextInt(9) + random.nextInt(9) + random.nextInt(9) + " " + random.nextInt(9) + random.nextInt(9) + random.nextInt(9) + random.nextInt(9) + random.nextInt(9) + random.nextInt(9); } return phoneNumber; } public static String getFirstName() { return FIRSTNAMES[random.nextInt(FIRSTNAMES.length)]; } public static String getSurname() { return SURNAMES[random.nextInt(SURNAMES.length)]; } public static String getFullName() { return getFirstName() + " " + getSurname(); } public static String getAddress() { String housenum = (random.nextInt(99) + 1) + " "; String road1 = ROADS1[random.nextInt(ROADS1.length)]; String road2 = ROADS2[random.nextInt(ROADS2.length)]; int townNum = random.nextInt(TOWNS.length); String town = TOWNS[townNum]; return housenum + road1 + " " + road2 + ", " + town; } public static String[] getAddressAndNumber() { String[] reply = new String[2]; String housenum = (random.nextInt(99) + 1) + " "; String road1 = ROADS1[random.nextInt(ROADS1.length)]; String road2 = ROADS2[random.nextInt(ROADS2.length)]; int townNum = random.nextInt(TOWNS.length); String town = TOWNS[townNum]; reply[0] = housenum + road1 + " " + road2 + ", " + town; reply[1] = getPhoneNumber(townNum < 5); return reply; } public static float getSalary() { return Math.round(10 + 90 * random.nextFloat()) * 1000; } private static final Random random = new Random(); private static final String[] FIRSTNAMES = { "Fred", "Jim", "Shiela", "Jack", "Betty", "Jacob", "Martha", "Kelly", "Luke", "Matt", "Gemma", "Joe", "Ben", "Jessie", "Leanne", "Becky", "William", "Jo" }; private static final String[] SURNAMES = { "Sutcliffe", "MacDonald", "Duckworth", "Smith", "Wisner", "Nield", "Turton", "Trelfer", "Wilson", "Johnson", "Daniels", "Jones", "Wilkinson", "Wilton" }; private static final String[] ROADS1 = { "Green", "Red", "Yellow", "Brown", "Blue", "Black", "White", }; private static final String[] ROADS2 = { "Close", "Drive", "Street", "Avenue", "Crescent", "Road", "Place", }; private static final String[] TOWNS = { "San Mateo", "San Francisco", "San Diego", "New York", "Atlanta", "Sandford", "York", "London", "Coventry", "Exeter", "Knowle", };
}
</source>
Redirect or reassign some standard descriptors
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; /**
* "Redirect" or reassign some standard descriptors. * * @author Ian F. Darwin, http://www.darwinsys.ru/ * @version $Id: Redirect.java,v 1.4 2004/03/06 20:57:56 ian Exp $ */
public class Redirect {
public static void main(String[] argv) throws IOException { //+ String LOGFILENAME = "error.log"; System.setErr(new PrintStream(new FileOutputStream(LOGFILENAME))); System.out.println("Please look for errors in " + LOGFILENAME); // Now assume this is somebody else"s code; you"ll see it writing to // stderr... int[] a = new int[5]; a[10] = 0; // here comes an ArrayIndexOutOfBoundsException //- }
}
</source>
Set JUnit Test case fail information
<source lang="java">
import junit.extensions.TestSetup; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; public class MainClass extends TestCase {
public static void main (String... args) { junit.textui.TestRunner.run (suite()); } public MainClass(String name) { super(name); } public void testPassNullsToConstructor() { try { Person p = new Person(null, null); fail("Expected IllegalArgumentException because both args are null"); } catch (IllegalArgumentException expected) { } } public void testNullsInName() { fail("sample failure"); Person p = new Person(null, "lastName"); assertEquals("lastName", p.getFullName()); p = new Person("Tanner", null); assertEquals("Tanner ?", p.getFullName()); } public static void oneTimeSetup() { System.out.println("oneTimeSetUp"); } public static void oneTimeTearDown() { System.out.println("oneTimeTearDown"); } public static Test suite() { TestSetup setup = new TestSetup(new TestSuite(MainClass.class)) { protected void setUp() throws Exception { oneTimeSetup(); } protected void tearDown() throws Exception { oneTimeTearDown(); } }; return setup; }
} class Person {
private String firstName; private String lastName; public Person(String firstName, String lastName) { if (firstName == null && lastName == null) { throw new IllegalArgumentException("Both names cannot be null"); } this.firstName = firstName; this.lastName = lastName; } public String getFullName() { String first = (this.firstName != null) ? this.firstName : "?"; String last = (this.lastName != null) ? this.lastName : "?"; return first + " " + last; } public String getFirstName() { return this.firstName; } public String getLastName() { return this.lastName; }
}
</source>
Simple Debugging
<source lang="java">
// : c15:SimpleDebugging.java // {ThrowsException} // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. public class SimpleDebugging {
private static void foo1() { System.out.println("In foo1"); foo2(); } private static void foo2() { System.out.println("In foo2"); foo3(); } private static void foo3() { System.out.println("In foo3"); int j = 1; j--; int i = 5 / j; } public static void main(String[] args) { foo1(); }
} ///:~
</source>
Simple test with JUnit
<source lang="java">
/* run:
[java] JVM args ignored when same JVM is used. [java] @BeforeClass: set up onece [java] .@Before: set up [java] Time: 0.015 [java] OK (1 test)
- /
import java.util.ArrayList; import java.util.List;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import junit.framework.JUnit4TestAdapter; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; /**
* Some simple tests. * */
public class MainClass{
public static void main (String... args) { junit.textui.TestRunner.run (suite()); } @BeforeClass public static void setUpOnce() { System.out.println("@BeforeClass: set up onece"); } @Before public void setUp() { System.out.println("@Before: set up "); } public static junit.framework.Test suite() { return new JUnit4TestAdapter(MainClass.class); } @Test public void testCopy() { assertTrue(1 == 1); }
}
</source>
Simple use of JUnit to test ArrayList
<source lang="java">
// : c15:JUnitDemo.java //Simple use of JUnit to test ArrayList //{Depends: junit.jar} //From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 //www.BruceEckel.ru. See copyright notice in CopyRight.txt. import java.util.*; import junit.framework.*; //So we can see the list objects being created, //and keep track of when they are cleaned up: class CountedList extends ArrayList {
private static int counter = 0; private int id = counter++; public CountedList() { System.out.println("CountedList #" + id); } public int getId() { return id; }
} public class JUnitDemo extends TestCase {
private CountedList list = new CountedList(); // You can use the constructor instead of setUp(): public JUnitDemo(String name) { super(name); for (int i = 0; i < 3; i++) list.add("" + i); } // Thus, setUp() is optional, but is run right // before the test: protected void setUp() { System.out.println("Set up for " + list.getId()); } // tearDown() is also optional, and is called after // each test. setUp() and tearDown() can be either // protected or public: public void tearDown() { System.out.println("Tearing down " + list.getId()); } // All tests have method names beginning with "test": public void testInsert() { System.out.println("Running testInsert()"); assertEquals(list.size(), 3); list.add(1, "Insert"); assertEquals(list.size(), 4); assertEquals(list.get(1), "Insert"); } public void testReplace() { System.out.println("Running testReplace()"); assertEquals(list.size(), 3); list.set(1, "Replace"); assertEquals(list.size(), 3); assertEquals(list.get(1), "Replace"); } // A "helper" method to reduce code duplication. As long // as the name doesn"t start with "test," it will not // be automatically executed by JUnit. private void compare(ArrayList lst, String[] strs) { Object[] array = lst.toArray(); assertTrue("Arrays not the same length", array.length == strs.length); for (int i = 0; i < array.length; i++) assertEquals(strs[i], (String) array[i]); } public void testOrder() { System.out.println("Running testOrder()"); compare(list, new String[] { "0", "1", "2" }); } public void testRemove() { System.out.println("Running testRemove()"); assertEquals(list.size(), 3); list.remove(1); assertEquals(list.size(), 2); compare(list, new String[] { "0", "2" }); } public void testAddAll() { System.out.println("Running testAddAll()"); list.addAll(Arrays.asList(new Object[] { "An", "African", "Swallow" })); assertEquals(list.size(), 6); compare(list, new String[] { "0", "1", "2", "An", "African", "Swallow" }); } public static void main(String[] args) { // Invoke JUnit on the class: junit.textui.TestRunner.run(JUnitDemo.class); }
} ///:~
</source>
Simple utility for testing program output
<source lang="java">
// : com:bruceeckel:simpletest:Test.java //Simple utility for testing program output. Intercepts //System.out to print both to the console and a buffer. //From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 //www.BruceEckel.ru. See copyright notice in CopyRight.txt. import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.regex.Pattern; public class Alias2 {
private static Test monitor = new Test(); private int i; public Alias2(int ii) { i = ii; } public static void f(Alias2 reference) { reference.i++; } public static void main(String[] args) { Alias2 x = new Alias2(7); System.out.println("x: " + x.i); System.out.println("Calling f(x)"); f(x); System.out.println("x: " + x.i); monitor.expect(new String[] { "x: 7", "Calling f(x)", "x: 8" }); }
} ///:~ class Test {
// Bit-shifted so they can be added together: public static final int EXACT = 1 << 0, // Lines must match exactly AT_LEAST = 1 << 1, // Must be at least these lines IGNORE_ORDER = 1 << 2, // Ignore line order WAIT = 1 << 3; // Delay until all lines are output private String className; private TestStream testStream; public Test() { // Discover the name of the class this // object was created within: className = new Throwable().getStackTrace()[1].getClassName(); testStream = new TestStream(className); } public static List fileToList(String fname) { ArrayList list = new ArrayList(); try { BufferedReader in = new BufferedReader(new FileReader(fname)); try { String line; while ((line = in.readLine()) != null) { if (fname.endsWith(".txt")) list.add(line); else list.add(new TestExpression(line)); } } finally { in.close(); } } catch (IOException e) { throw new RuntimeException(e); } return list; } public static List arrayToList(Object[] array) { List l = new ArrayList(); for (int i = 0; i < array.length; i++) { if (array[i] instanceof TestExpression) { TestExpression re = (TestExpression) array[i]; for (int j = 0; j < re.getNumber(); j++) l.add(re); } else { l.add(new TestExpression(array[i].toString())); } } return l; } public void expect(Object[] exp, int flags) { if ((flags & WAIT) != 0) while (testStream.numOfLines < exp.length) { try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } List output = fileToList(className + "Output.txt"); if ((flags & IGNORE_ORDER) == IGNORE_ORDER) OutputVerifier.verifyIgnoreOrder(output, exp); else if ((flags & AT_LEAST) == AT_LEAST) OutputVerifier.verifyAtLeast(output, arrayToList(exp)); else OutputVerifier.verify(output, arrayToList(exp)); // Clean up the output file - see c06:Detergent.java testStream.openOutputFile(); } public void expect(Object[] expected) { expect(expected, EXACT); } public void expect(Object[] expectFirst, String fname, int flags) { List expected = fileToList(fname); for (int i = 0; i < expectFirst.length; i++) expected.add(i, expectFirst[i]); expect(expected.toArray(), flags); } public void expect(Object[] expectFirst, String fname) { expect(expectFirst, fname, EXACT); } public void expect(String fname) { expect(new Object[] {}, fname, EXACT); }
} ///:~ class TestExpression implements Comparable {
private Pattern p; private String expression; private boolean isRegEx; // Default to only one instance of this expression: private int duplicates = 1; public TestExpression(String s) { this.expression = s; if (expression.startsWith("%% ")) { this.isRegEx = true; expression = expression.substring(3); this.p = Pattern.rupile(expression); } } // For duplicate instances: public TestExpression(String s, int duplicates) { this(s); this.duplicates = duplicates; } public String toString() { if (isRegEx) return p.pattern(); return expression; } public boolean equals(Object obj) { if (this == obj) return true; if (isRegEx) return (compareTo(obj) == 0); return expression.equals(obj.toString()); } public int compareTo(Object obj) { if ((isRegEx) && (p.matcher(obj.toString()).matches())) return 0; return expression.rupareTo(obj.toString()); } public int getNumber() { return duplicates; } public String getExpression() { return expression; } public boolean isRegEx() { return isRegEx; }
} ///:~ class TestStream extends PrintStream {
protected int numOfLines; private PrintStream console = System.out, err = System.err, fout; // To store lines sent to System.out or err private InputStream stdin; private String className; public TestStream(String className) { super(System.out, true); // Autoflush System.setOut(this); System.setErr(this); stdin = System.in; // Save to restore in dispose() // Replace the default version with one that // automatically produces input on demand: System.setIn(new BufferedInputStream(new InputStream() { char[] input = ("test\n").toCharArray(); int index = 0; public int read() { return (int) input[index = (index + 1) % input.length]; } })); this.className = className; openOutputFile(); } // public PrintStream getConsole() { return console; } public void dispose() { System.setOut(console); System.setErr(err); System.setIn(stdin); } // This will write over an old Output.txt file: public void openOutputFile() { try { fout = new PrintStream(new FileOutputStream(new File(className + "Output.txt"))); } catch (FileNotFoundException e) { throw new RuntimeException(e); } } // Override all possible print/println methods to send // intercepted console output to both the console and // the Output.txt file: public void print(boolean x) { console.print(x); fout.print(x); } public void println(boolean x) { numOfLines++; console.println(x); fout.println(x); } public void print(char x) { console.print(x); fout.print(x); } public void println(char x) { numOfLines++; console.println(x); fout.println(x); } public void print(int x) { console.print(x); fout.print(x); } public void println(int x) { numOfLines++; console.println(x); fout.println(x); } public void print(long x) { console.print(x); fout.print(x); } public void println(long x) { numOfLines++; console.println(x); fout.println(x); } public void print(float x) { console.print(x); fout.print(x); } public void println(float x) { numOfLines++; console.println(x); fout.println(x); } public void print(double x) { console.print(x); fout.print(x); } public void println(double x) { numOfLines++; console.println(x); fout.println(x); } public void print(char[] x) { console.print(x); fout.print(x); } public void println(char[] x) { numOfLines++; console.println(x); fout.println(x); } public void print(String x) { console.print(x); fout.print(x); } public void println(String x) { numOfLines++; console.println(x); fout.println(x); } public void print(Object x) { console.print(x); fout.print(x); } public void println(Object x) { numOfLines++; console.println(x); fout.println(x); } public void println() { if (false) console.print("println"); numOfLines++; console.println(); fout.println(); } public void write(byte[] buffer, int offset, int length) { console.write(buffer, offset, length); fout.write(buffer, offset, length); } public void write(int b) { console.write(b); fout.write(b); }
} ///:~ class OutputVerifier {
private static void verifyLength(int output, int expected, int compare) { if ((compare == Test.EXACT && expected != output) || (compare == Test.AT_LEAST && output < expected)) throw new NumOfLinesException(expected, output); } public static void verify(List output, List expected) { verifyLength(output.size(), expected.size(), Test.EXACT); if (!expected.equals(output)) { //find the line of mismatch ListIterator it1 = expected.listIterator(); ListIterator it2 = output.listIterator(); while (it1.hasNext() && it2.hasNext() && it1.next().equals(it2.next())) ; throw new LineMismatchException(it1.nextIndex(), it1.previous() .toString(), it2.previous().toString()); } } public static void verifyIgnoreOrder(List output, Object[] expected) { verifyLength(expected.length, output.size(), Test.EXACT); if (!(expected instanceof String[])) throw new RuntimeException( "IGNORE_ORDER only works with String objects"); String[] out = new String[output.size()]; Iterator it = output.iterator(); for (int i = 0; i < out.length; i++) out[i] = it.next().toString(); Arrays.sort(out); Arrays.sort(expected); int i = 0; if (!Arrays.equals(expected, out)) { while (expected[i].equals(out[i])) { i++; } throw new SimpleTestException(((String) out[i]).rupareTo(expected[i]) < 0 ? "output: <" + out[i] + ">" : "expected: <" + expected[i] + ">"); } } public static void verifyAtLeast(List output, List expected) { verifyLength(output.size(), expected.size(), Test.AT_LEAST); if (!output.containsAll(expected)) { ListIterator it = expected.listIterator(); while (output.contains(it.next())) { } throw new SimpleTestException("expected: <" + it.previous().toString() + ">"); } }
} ///:~ class SimpleTestException extends RuntimeException {
public SimpleTestException(String msg) { super(msg); }
} ///:~ class NumOfLinesException extends SimpleTestException {
public NumOfLinesException(int exp, int out) { super("Number of lines of output and " + "expected output did not match.\n" + "expected: <" + exp + ">\n" + "output: <" + out + "> lines)"); }
} ///:~ class LineMismatchException extends SimpleTestException {
public LineMismatchException(int lineNum, String expected, String output) { super("line " + lineNum + " of output did not match expected output\n" + "expected: <" + expected + ">\n" + "output: <" + output + ">"); }
} ///:~
</source>
Testing class Class
<source lang="java">
// : c10:ToyTest.java // Testing class Class. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. interface HasBatteries { } interface Waterproof { } interface Shoots { } class Toy {
// Comment out the following default constructor // to see NoSuchMethodError from (*1*) Toy() { } Toy(int i) { }
} class FancyToy extends Toy implements HasBatteries, Waterproof, Shoots {
FancyToy() { super(1); }
} public class ToyTest {
static void printInfo(Class cc) { System.out.println("Class name: " + cc.getName() + " is interface? [" + cc.isInterface() + "]"); } public static void main(String[] args) { Class c = null; try { c = Class.forName("FancyToy"); } catch (ClassNotFoundException e) { System.out.println("Can"t find FancyToy"); System.exit(1); } printInfo(c); Class[] faces = c.getInterfaces(); for (int i = 0; i < faces.length; i++) printInfo(faces[i]); Class cy = c.getSuperclass(); Object o = null; try { // Requires default constructor: o = cy.newInstance(); // (*1*) } catch (InstantiationException e) { System.out.println("Cannot instantiate"); System.exit(1); } catch (IllegalAccessException e) { System.out.println("Cannot access"); System.exit(1); } printInfo(o.getClass()); }
} ///:~
</source>
Utilities for debugging
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
/**
* Utilities for debugging * * @author Ian Darwin, http://www.darwinsys.ru/ * @version $Id: Debug.java,v 1.8 2004/01/31 01:26:06 ian Exp $ */
public class Debug {
/** * Static method to see if a given category of debugging is enabled. Enable * by setting e.g., -Ddebug.fileio to debug file I/O operations. For * example:
if (Debug.isEnabled("fileio"))
* System.out.println("Starting to read file " + fileName); */ public static boolean isEnabled(String category) { return System.getProperty("debug." + category) != null; } /** * Static method to println a given message if the given category is enabled * for debugging, as reported by isEnabled. */ public static void println(String category, String msg) { if (isEnabled(category)) System.out.println(msg); } /** * Static method to println an arbitrary Objecct if the given category is * enabled for debugging, as reported by isEnabled. */ public static void println(String category, Object stuff) { println(category, stuff.toString()); }
}
</source>