### Question:
ThrowableFingerprintCalculator { public String calculateFingerprint(Throwable t) { MessageDigest md5 = getMD5Instance(); PrintStream ps = new PrintStream(new DigestOutputStream(new DoNothingOutputStream(), md5)); t.printStackTrace(ps); return base64Encoder.encodeToString(md5.digest()); }  String calculateFingerprint(Throwable t);  }### Answer:
@Test public void calculateFingerprint_shouldGenerateTheSameFingerprint_givenTwoIdenticalThrowables() throws Exception { String exceptionMessage = "message"; Throwable firstException = new RuntimeException(exceptionMessage); Throwable secondException = new RuntimeException(exceptionMessage); firstException.setStackTrace(constructCustomStackTrace()); secondException.setStackTrace(constructCustomStackTrace()); String firstFingerprint = calculator.calculateFingerprint(firstException); String secondFingerprint = calculator.calculateFingerprint(secondException); assertEquals(firstFingerprint, secondFingerprint); }
@Test public void calculateFingerprint_shouldReturnTheSameFingerprint_givenTheSameExceptionTwice() throws Exception { Throwable t = new RuntimeException(); String expectedFingerprint = calculator.calculateFingerprint(t); String actualFingerprint = calculator.calculateFingerprint(t); assertEquals(expectedFingerprint, actualFingerprint); }
@Test public void calculateFingerprint_shouldReturnADifferentFingerprint_whenTheStackTraceChanges() throws Exception { Throwable t = new RuntimeException(); String originalFingerprint = calculator.calculateFingerprint(t); t.setStackTrace(constructCustomStackTrace()); String newFingerprint = calculator.calculateFingerprint(t); assertNotEquals(originalFingerprint, newFingerprint); }
@Test public void calculateFingerprint_shouldReturnDifferentFingerprints_forDifferentThrowableTypes() throws Exception { String message = "foo"; Throwable a = new Exception(message); a.setStackTrace(constructCustomStackTrace()); Throwable b = new RuntimeException(message); b.setStackTrace(constructCustomStackTrace()); String fingerprintA = calculator.calculateFingerprint(a); String fingerprintB = calculator.calculateFingerprint(b); assertNotEquals(fingerprintA, fingerprintB); }
@Test public void calculateFingerprint_shouldReturnDifferentFingerprints_givenDifferentMessages() throws Exception { Throwable a = new RuntimeException("a"); a.setStackTrace(constructCustomStackTrace()); Throwable b = new RuntimeException("b"); b.setStackTrace(constructCustomStackTrace()); String fingerprintA = calculator.calculateFingerprint(a); String fingerprintB = calculator.calculateFingerprint(b); assertNotEquals(fingerprintA, fingerprintB); }
@Test public void calculateFingerprint_shouldReturnADifferentFingerprint_givenADifferentCause() throws Exception { Throwable t = new RuntimeException(); String originalFingerprint = calculator.calculateFingerprint(t); t.initCause(new RuntimeException()); String modifiedFingerprint = calculator.calculateFingerprint(t); assertNotEquals(originalFingerprint, modifiedFingerprint); }
@Test public void calculateFingerprint_shouldReturnADifferentFingerprint_givenAChangeInSuppressedExceptions() throws Exception { Throwable t = new RuntimeException(); String originalFingerprint = calculator.calculateFingerprint(t); t.addSuppressed(new RuntimeException()); String modifiedFingerprint = calculator.calculateFingerprint(t); assertNotEquals(originalFingerprint, modifiedFingerprint); }