最近在讀multi-thread context(MTC)源碼,發現一個好用的工具:CoreMatchers,其提供了不少匹配器,對於junit相對單薄的斷言功能是種很好的補充html
而CoreMatchers的中文說明很是少,也不多見人使用,先展現一段測試代碼java
1 import com.alibaba.mtc.testmodel.Call; 2 import org.junit.AfterClass; 3 import org.junit.Test; 4 5 import java.util.Arrays; 6 import java.util.List; 7 import java.util.concurrent.Callable; 8 import java.util.concurrent.ConcurrentMap; 9 import java.util.concurrent.ExecutionException; 10 import java.util.concurrent.ExecutorService; 11 import java.util.concurrent.Executors; 12 import java.util.concurrent.Future; 13 14 import static com.alibaba.mtc.Utils.CHILD; 15 import static com.alibaba.mtc.Utils.PARENT_AFTER_CREATE_MTC_TASK; 16 import static com.alibaba.mtc.Utils.PARENT_MODIFIED_IN_CHILD; 17 import static com.alibaba.mtc.Utils.PARENT_UNMODIFIED_IN_CHILD; 18 import static com.alibaba.mtc.Utils.assertMtContext; 19 import static com.alibaba.mtc.Utils.copied; 20 import static com.alibaba.mtc.Utils.createTestMtContexts; 21 import static com.alibaba.mtc.Utils.expandThreadPool; 22 import static org.hamcrest.CoreMatchers.containsString; 23 import static org.hamcrest.CoreMatchers.instanceOf; 24 import static org.junit.Assert.assertEquals; 25 import static org.junit.Assert.assertNull; 26 import static org.junit.Assert.assertSame; 27 import static org.junit.Assert.assertThat; 28 import static org.junit.Assert.fail; 29 30 31 public class MtContextCallableTest { 32 static ExecutorService executorService = Executors.newFixedThreadPool(3); 33 34 static { 35 expandThreadPool(executorService); 36 } 37 38 @AfterClass 39 public static void afterClass() throws Exception { 40 executorService.shutdown(); 41 } 42 43 @Test 44 public void test_MtContextCallable_inSameThread() throws Exception { 45 ConcurrentMap<String, MtContextThreadLocal<String>> mtContexts = createTestMtContexts(); 46 47 Call call = new Call("1", mtContexts); 48 MtContextCallable<String> mtContextCallable = MtContextCallable.<String>get(call); 49 50 // create after new Task, won't see parent value in in task! 51 MtContextThreadLocal<String> after = new MtContextThreadLocal<String>(); 52 after.set(PARENT_AFTER_CREATE_MTC_TASK); 53 mtContexts.put(PARENT_AFTER_CREATE_MTC_TASK, after); 54 55 String ret = mtContextCallable.call(); 56 assertEquals("ok", ret); 57 58 // child Inheritable 59 assertMtContext(call.copied, 60 PARENT_UNMODIFIED_IN_CHILD, PARENT_UNMODIFIED_IN_CHILD, 61 PARENT_MODIFIED_IN_CHILD + 1, PARENT_MODIFIED_IN_CHILD, 62 CHILD + 1, CHILD + 1 63 ); 64 65 // child do not effect parent 66 assertMtContext(copied(mtContexts), 67 PARENT_UNMODIFIED_IN_CHILD, PARENT_UNMODIFIED_IN_CHILD, 68 PARENT_MODIFIED_IN_CHILD, PARENT_MODIFIED_IN_CHILD, // restored after call! 69 PARENT_AFTER_CREATE_MTC_TASK, PARENT_AFTER_CREATE_MTC_TASK 70 ); 71 } 72 73 @Test 74 public void test_MtContextCallable_asyncWithExecutorService() throws Exception { 75 ConcurrentMap<String, MtContextThreadLocal<String>> mtContexts = createTestMtContexts(); 76 77 Call call = new Call("1", mtContexts); 78 MtContextCallable<String> mtContextCallable = MtContextCallable.get(call); 79 80 // create after new Task, won't see parent value in in task! 81 MtContextThreadLocal<String> after = new MtContextThreadLocal<String>(); 82 after.set(PARENT_AFTER_CREATE_MTC_TASK); 83 mtContexts.put(PARENT_AFTER_CREATE_MTC_TASK, after); 84 85 Future future = executorService.submit(mtContextCallable); 86 assertEquals("ok", future.get()); 87 88 // child Inheritable 89 assertMtContext(call.copied, 90 PARENT_UNMODIFIED_IN_CHILD, PARENT_UNMODIFIED_IN_CHILD, 91 PARENT_MODIFIED_IN_CHILD + 1, PARENT_MODIFIED_IN_CHILD, 92 CHILD + 1, CHILD + 1 93 ); 94 95 // child do not effect parent 96 assertMtContext(copied(mtContexts), 97 PARENT_UNMODIFIED_IN_CHILD, PARENT_UNMODIFIED_IN_CHILD, 98 PARENT_MODIFIED_IN_CHILD, PARENT_MODIFIED_IN_CHILD, 99 PARENT_AFTER_CREATE_MTC_TASK, PARENT_AFTER_CREATE_MTC_TASK 100 ); 101 } 102 103 @Test 104 public void test_removeSameAsNotSet() throws Exception { 105 ConcurrentMap<String, MtContextThreadLocal<String>> mtContexts = createTestMtContexts(); 106 mtContexts.get(PARENT_UNMODIFIED_IN_CHILD).remove(); 107 108 Call call = new Call("1", mtContexts); 109 MtContextCallable<String> mtContextCallable = MtContextCallable.get(call); 110 111 // create after new Task, won't see parent value in in task! 112 MtContextThreadLocal<String> after = new MtContextThreadLocal<String>(); 113 after.set(PARENT_AFTER_CREATE_MTC_TASK); 114 mtContexts.put(PARENT_AFTER_CREATE_MTC_TASK, after); 115 116 Future future = executorService.submit(mtContextCallable); 117 assertEquals("ok", future.get()); 118 119 // child Inheritable 120 assertMtContext(call.copied, 121 PARENT_MODIFIED_IN_CHILD + 1, PARENT_MODIFIED_IN_CHILD, 122 CHILD + 1, CHILD + 1 123 ); 124 125 // child do not effect parent 126 assertMtContext(copied(mtContexts), 127 PARENT_MODIFIED_IN_CHILD, PARENT_MODIFIED_IN_CHILD, 128 PARENT_AFTER_CREATE_MTC_TASK, PARENT_AFTER_CREATE_MTC_TASK 129 ); 130 } 131 132 @Test 133 public void test_releaseMtContextAfterCall() throws Exception { 134 ConcurrentMap<String, MtContextThreadLocal<String>> mtContexts = createTestMtContexts(); 135 136 Call call = new Call("1", mtContexts); 137 MtContextCallable<String> mtContextCallable = MtContextCallable.get(call, true); 138 assertSame(call, mtContextCallable.getCallable()); 139 140 Future future = executorService.submit(mtContextCallable); 141 assertEquals("ok", future.get()); 142 143 future = executorService.submit(mtContextCallable); 144 try { 145 future.get(); 146 fail(); 147 } catch (ExecutionException expected) { 148 assertThat(expected.getCause(), instanceOf(IllegalStateException.class)); 149 assertThat(expected.getMessage(), containsString("MtContext is released!")); 150 } 151 } 152 153 @Test 154 public void test_get_same() throws Exception { 155 Call call = new Call("1", null); 156 MtContextCallable<String> mtContextCallable = MtContextCallable.get(call); 157 assertSame(call, mtContextCallable.getCallable()); 158 } 159 160 @Test 161 public void test_get_idempotent() throws Exception { 162 MtContextCallable<String> call = MtContextCallable.get(new Call("1", null)); 163 try { 164 MtContextCallable.get(call); 165 fail(); 166 } catch (IllegalStateException e) { 167 assertThat(e.getMessage(), containsString("Already MtContextCallable")); 168 } 169 } 170 171 @Test 172 public void test_get_nullInput() throws Exception { 173 assertNull(MtContextCallable.get(null)); 174 } 175 176 @Test 177 public void test_gets() throws Exception { 178 Callable<String> call1 = new Call("1", null); 179 Callable<String> call2 = new Call("1", null); 180 Callable<String> call3 = new Call("1", null); 181 182 @SuppressWarnings("unchecked") 183 List<MtContextCallable<String>> callList = MtContextCallable.gets( 184 Arrays.asList(call1, call2, null, call3)); 185 186 assertEquals(4, callList.size()); 187 assertThat(callList.get(0), instanceOf(MtContextCallable.class)); 188 assertThat(callList.get(1), instanceOf(MtContextCallable.class)); 189 assertNull(callList.get(2)); 190 assertThat(callList.get(3), instanceOf(MtContextCallable.class)); 191 } 192 }
好在方法命名都很簡單, 附上其java docexpress
限定符和類型 | 方法和說明 |
---|---|
static <T> Matcher<T> |
allOf(java.lang.Iterable<Matcher<? super T>> matchers)
Creates a matcher that matches if the examined object matches
ALL of the specified matchers.
|
static <T> Matcher<T> |
allOf(Matcher<? super T>... matchers)
Creates a matcher that matches if the examined object matches
ALL of the specified matchers.
|
static <T> Matcher<T> |
allOf(Matcher<? super T> first, Matcher<? super T> second)
Creates a matcher that matches if the examined object matches
ALL of the specified matchers.
|
static <T> Matcher<T> |
allOf(Matcher<? super T> first, Matcher<? super T> second, Matcher<? super T> third)
Creates a matcher that matches if the examined object matches
ALL of the specified matchers.
|
static <T> Matcher<T> |
allOf(Matcher<? super T> first, Matcher<? super T> second, Matcher<? super T> third, Matcher<? super T> fourth)
Creates a matcher that matches if the examined object matches
ALL of the specified matchers.
|
static <T> Matcher<T> |
allOf(Matcher<? super T> first, Matcher<? super T> second, Matcher<? super T> third, Matcher<? super T> fourth, Matcher<? super T> fifth)
Creates a matcher that matches if the examined object matches
ALL of the specified matchers.
|
static <T> Matcher<T> |
allOf(Matcher<? super T> first, Matcher<? super T> second, Matcher<? super T> third, Matcher<? super T> fourth, Matcher<? super T> fifth, Matcher<? super T> sixth)
Creates a matcher that matches if the examined object matches
ALL of the specified matchers.
|
static <T> Matcher<T> |
any(java.lang.Class<T> type)
Creates a matcher that matches when the examined object is an instance of the specified
type , as determined by calling the
Class.isInstance(Object) method on that type, passing the the examined object.
|
static <T> AnyOf<T> |
anyOf(java.lang.Iterable<Matcher<? super T>> matchers)
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static <T> AnyOf<T> |
anyOf(Matcher<? super T>... matchers)
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static <T> AnyOf<T> |
anyOf(Matcher<T> first, Matcher<? super T> second)
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static <T> AnyOf<T> |
anyOf(Matcher<T> first, Matcher<? super T> second, Matcher<? super T> third)
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static <T> AnyOf<T> |
anyOf(Matcher<T> first, Matcher<? super T> second, Matcher<? super T> third, Matcher<? super T> fourth)
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static <T> AnyOf<T> |
anyOf(Matcher<T> first, Matcher<? super T> second, Matcher<? super T> third, Matcher<? super T> fourth, Matcher<? super T> fifth)
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static <T> AnyOf<T> |
anyOf(Matcher<T> first, Matcher<? super T> second, Matcher<? super T> third, Matcher<? super T> fourth, Matcher<? super T> fifth, Matcher<? super T> sixth)
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static Matcher<java.lang.Object> |
anything()
Creates a matcher that always matches, regardless of the examined object.
|
static Matcher<java.lang.Object> |
anything(java.lang.String description)
Creates a matcher that always matches, regardless of the examined object, but describes itself with the specified
String .
|
static <LHS> CombinableMatcher.CombinableBothMatcher<LHS> |
both(Matcher<? super LHS> matcher)
Creates a matcher that matches when both of the specified matchers match the examined object.
|
static Matcher<java.lang.String> |
containsString(java.lang.String substring)
Creates a matcher that matches if the examined
String contains the specified
String anywhere.
|
static <T> Matcher<T> |
describedAs(java.lang.String description, Matcher<T> matcher, java.lang.Object... values)
Wraps an existing matcher, overriding its description with that specified.
|
static <LHS> CombinableMatcher.CombinableEitherMatcher<LHS> |
either(Matcher<? super LHS> matcher)
Creates a matcher that matches when either of the specified matchers match the examined object.
|
static Matcher<java.lang.String> |
endsWith(java.lang.String suffix)
Creates a matcher that matches if the examined
String ends with the specified
String .
|
static <T> Matcher<T> |
equalTo(T operand)
Creates a matcher that matches when the examined object is logically equal to the specified
operand , as determined by calling the
Object.equals(java.lang.Object) method on the
examinedobject.
|
static <U> Matcher<java.lang.Iterable<U>> |
everyItem(Matcher<U> itemMatcher)
Creates a matcher for
Iterable s that only matches when a single pass over the examined
Iterable yields items that are all matched by the specified
itemMatcher .
|
static <T> Matcher<java.lang.Iterable<? super T>> |
hasItem(Matcher<? super T> itemMatcher)
Creates a matcher for
Iterable s that only matches when a single pass over the examined
Iterable yields at least one item that is matched by the specified
itemMatcher .
|
static <T> Matcher<java.lang.Iterable<? super T>> |
hasItem(T item)
Creates a matcher for
Iterable s that only matches when a single pass over the examined
Iterable yields at least one item that is equal to the specified
item .
|
static <T> Matcher<java.lang.Iterable<T>> |
hasItems(Matcher<? super T>... itemMatchers)
Creates a matcher for
Iterable s that matches when consecutive passes over the examined
Iterable yield at least one item that is matched by the corresponding matcher from the specified
itemMatchers .
|
static <T> Matcher<java.lang.Iterable<T>> |
hasItems(T... items)
Creates a matcher for
Iterable s that matches when consecutive passes over the examined
Iterable yield at least one item that is equal to the corresponding item from the specified
items .
|
static <T> Matcher<T> |
instanceOf(java.lang.Class<?> type)
Creates a matcher that matches when the examined object is an instance of the specified
type , as determined by calling the
Class.isInstance(Object) method on that type, passing the the examined object.
|
static <T> Matcher<T> |
is(java.lang.Class<T> type)
已過期。
use isA(Class type) instead.
|
static <T> Matcher<T> |
is(Matcher<T> matcher)
Decorates another Matcher, retaining its behaviour, but allowing tests to be slightly more expressive.
|
static <T> Matcher<T> |
is(T value)
A shortcut to the frequently used
is(equalTo(x)) .
|
static <T> Matcher<T> |
isA(java.lang.Class<T> type)
A shortcut to the frequently used
is(instanceOf(SomeClass.class)) .
|
static <T> Matcher<T> |
not(Matcher<T> matcher)
Creates a matcher that wraps an existing matcher, but inverts the logic by which it will match.
|
static <T> Matcher<T> |
not(T value)
A shortcut to the frequently used
not(equalTo(x)) .
|
static Matcher<java.lang.Object> |
notNullValue()
A shortcut to the frequently used
not(nullValue()) .
|
static <T> Matcher<T> |
notNullValue(java.lang.Class<T> type)
A shortcut to the frequently used
not(nullValue(X.class)).
|
static Matcher<java.lang.Object> |
nullValue()
Creates a matcher that matches if examined object is
null .
|
static <T> Matcher<T> |
nullValue(java.lang.Class<T> type)
Creates a matcher that matches if examined object is
null .
|
static <T> Matcher<T> |
sameInstance(T target)
Creates a matcher that matches only when the examined object is the same instance as the specified target object.
|
static Matcher<java.lang.String> |
startsWith(java.lang.String prefix)
Creates a matcher that matches if the examined
String starts with the specified
String .
|
static <T> Matcher<T> |
theInstance(T target)
Creates a matcher that matches only when the examined object is the same instance as the specified target object.
|