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