1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 6 package org.mockitoutil; 7 8 import org.assertj.core.api.Condition; 9 import org.junit.After; 10 import org.junit.Before; 11 import org.mockito.MockitoAnnotations; 12 import org.mockito.StateMaster; 13 import org.mockito.internal.MockitoCore; 14 import org.mockito.internal.configuration.ConfigurationAccess; 15 import org.mockito.internal.invocation.mockref.MockStrongReference; 16 import org.mockito.internal.invocation.InterceptedInvocation; 17 import org.mockito.internal.debugging.LocationImpl; 18 import org.mockito.internal.invocation.InvocationBuilder; 19 import org.mockito.internal.invocation.InvocationMatcher; 20 import org.mockito.internal.invocation.SerializableMethod; 21 import org.mockito.invocation.Invocation; 22 23 import java.io.ByteArrayOutputStream; 24 import java.io.IOException; 25 import java.io.PrintStream; 26 27 import static org.mockito.Mockito.mock; 28 29 /** 30 * the easiest way to make sure that tests clean up invalid state is to require 31 * valid state for all tests. 32 */ 33 public class TestBase { 34 35 /** 36 * Condition to be used with AssertJ 37 */ hasMessageContaining(final String substring)38 public static Condition<Throwable> hasMessageContaining(final String substring) { 39 return new Condition<Throwable>() { 40 @Override 41 public boolean matches(Throwable e) { 42 return e.getMessage().contains(substring); 43 } 44 }; 45 } 46 47 @After 48 public void cleanUpConfigInAnyCase() { 49 ConfigurationAccess.getConfig().overrideCleansStackTrace(false); 50 ConfigurationAccess.getConfig().overrideDefaultAnswer(null); 51 StateMaster state = new StateMaster(); 52 //catch any invalid state left over after test case run 53 //this way we can catch early if some Mockito operations leave weird state afterwards 54 state.validate(); 55 //reset the state, especially, reset any ongoing stubbing for correct error messages of tests that assert unhappy paths 56 state.reset(); 57 } 58 59 @Before 60 public void init() { 61 MockitoAnnotations.initMocks(this); 62 } 63 64 public static void makeStackTracesClean() { 65 ConfigurationAccess.getConfig().overrideCleansStackTrace(true); 66 } 67 68 public void resetState() { 69 new StateMaster().reset(); 70 } 71 72 public static Invocation getLastInvocation() { 73 return new MockitoCore().getLastInvocation(); 74 } 75 76 protected static Invocation invocationOf(Class<?> type, String methodName, Object ... args) throws NoSuchMethodException { 77 Class<?>[] types = new Class<?>[args.length]; 78 for (int i = 0; i < args.length; i++) { 79 types[i] = args[i].getClass(); 80 } 81 return new InterceptedInvocation(new MockStrongReference<Object>(mock(type), false), 82 new SerializableMethod(type.getMethod(methodName, types)), args, InterceptedInvocation.NO_OP, 83 new LocationImpl(), 1); 84 } 85 86 protected static Invocation invocationAt(String location) { 87 return new InvocationBuilder().location(location).toInvocation(); 88 } 89 90 protected static InvocationMatcher invocationMatcherAt(String location) { 91 return new InvocationBuilder().location(location).toInvocationMatcher(); 92 } 93 94 protected String getStackTrace(Throwable e) { 95 ByteArrayOutputStream out = new ByteArrayOutputStream(); 96 e.printStackTrace(new PrintStream(out)); 97 try { 98 out.close(); 99 } catch (IOException ex) {} 100 return out.toString(); 101 } 102 103 /** 104 * Filters out unwanted line numbers from provided stack trace String. 105 * This is useful for writing assertions for exception messages that contain line numbers. 106 * 107 * For example it turns: 108 * blah blah (UnusedStubsExceptionMessageTest.java:27) 109 * into: 110 * blah blah (UnusedStubsExceptionMessageTest.java:0) 111 */ 112 public static String filterLineNo(String stackTrace) { 113 return stackTrace.replaceAll("(\\((\\w+\\.java):(\\d)+\\))", "($2:0)"); 114 } 115 116 /** 117 * Filters out hashCode from the text. Useful for writing assertions that contain the String representation of mock objects 118 * @param text to filter 119 * @return filtered text 120 */ 121 public static String filterHashCode(String text) { 122 return text.replaceAll("hashCode: (\\d)+\\.", "hashCode: xxx."); 123 } 124 } 125