Java/Development Class/Unit Test — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Текущая версия на 07:06, 1 июня 2010
Содержание
- 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
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));
}
}
Assert equals: Long
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));
}
}
Assertion tool for debugging
//: 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);
}
} ///:~
Before annotation
/*
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);
}
}
Debug frame
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();
}
}
}
Demonstration of Design by Contract (DBC) combined with white-box unit testing
// : 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);
}
} ///:~
Error Handler
/*
* 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
*
* <pre>
*
* public void handle(Throwable t)
*
* </pre>.
* <p>
* 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());
}
}
JUnit assertEquals: Float With Delta
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);
}
}
JUnit assertEquals With Message
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);
}
}
JUnit assertTrue
/*
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);
}
}
JUnit assertTrue: ObjectArray
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});
}
}
JUnit BeforeClass
/*
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);
}
}
JUnit Extends TestCase
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);
}
}
JUnit Ignore
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);
}
}
JUnit Test Case With Expected Exception
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
}
}
JUnit Test Setup
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() {
}
}
Random data for test
/*
* 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",
};
}
Redirect or reassign some standard descriptors
/*
* 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
//-
}
}
Set JUnit Test case fail information
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;
}
}
Simple Debugging
// : 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();
}
} ///:~
Simple test with JUnit
/*
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);
}
}
Simple use of JUnit to test ArrayList
// : 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);
}
} ///:~
Simple utility for testing program output
// : 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
+ ">");
}
} ///:~
Testing class Class
// : 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());
}
} ///:~
Utilities for debugging
/*
* 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: <br/>if (Debug.isEnabled("fileio")) <br/>
* 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());
}
}