package junit.tests.runner; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.List; import junit.framework.TestCase; import junit.tests.framework.Success; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure; import org.junit.tests.running.methods.AnnotationTest; public class ResultTest extends TestCase { public void testRunFailureResultCanBeSerialised() throws Exception { JUnitCore runner = new JUnitCore(); Result result = runner.run(AnnotationTest.FailureTest.class); assertResultSerializable(result); } public void testRunSuccessResultCanBeSerialised() throws Exception { JUnitCore runner = new JUnitCore(); Result result = runner.run(Success.class); assertResultSerializable(result); } private void assertResultSerializable(Result result) throws IOException, ClassNotFoundException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); new ObjectOutputStream(byteArrayOutputStream).writeObject(result); byte[] bytes = byteArrayOutputStream.toByteArray(); ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bytes)); Result fromStream = (Result) objectInputStream.readObject(); assertSerializedCorrectly(result, fromStream); InputStream resource = getClass().getResourceAsStream(getName()); assertNotNull("Could not read resource " + getName(), resource); objectInputStream = new ObjectInputStream(resource); fromStream = (Result) objectInputStream.readObject(); assertSerializedCorrectly(new ResultWithFixedRunTime(result), fromStream); } /** * A version of {@code Result} that returns a hard-coded runtime. * This makes values returned by the methods deterministic. */ private static class ResultWithFixedRunTime extends Result { private final Result delegate; public ResultWithFixedRunTime(Result delegate) { this.delegate = delegate; } @Override public int getRunCount() { return delegate.getRunCount(); } @Override public int getFailureCount() { return delegate.getFailureCount(); } @Override public long getRunTime() { return 2; } @Override public List<Failure> getFailures() { return delegate.getFailures(); } @Override public int getIgnoreCount() { return delegate.getIgnoreCount(); } } private void assertSerializedCorrectly(Result result, Result fromStream) { assertNotNull(fromStream); // Exceptions don't implement equals() so we need to compare field by field assertEquals("failureCount", result.getFailureCount(), fromStream.getFailureCount()); assertEquals("ignoreCount", result.getIgnoreCount(), fromStream.getIgnoreCount()); assertEquals("runTime", result.getRunTime(), fromStream.getRunTime()); assertEquals("failures", result.getFailures().size(), fromStream.getFailures().size()); int index = 0; for (Failure failure : result.getFailures()) { Failure failureFromStream = fromStream.getFailures().get(index); String messagePrefix = String.format("failures[%d]", index++); assertEquals(messagePrefix + ".description", failure.getDescription(), failureFromStream.getDescription()); Throwable exception = failure.getException(); Throwable exceptionFromStream = failureFromStream.getException(); assertEquals(messagePrefix + ".exception", exception.getClass(), exceptionFromStream.getClass()); assertEquals(messagePrefix + ".exception", exception.getMessage(), exceptionFromStream.getMessage()); } } }