最近在读multi-thread context(MTC)源码,发现一个好用的工具:CoreMatchers,其提供了很多匹配器,对于junit相对单薄的断言功能是种很好的补充
而CoreMatchers的中文说明非常少,也很少见人使用,先展示一段测试代码
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> mtContexts = createTestMtContexts(); 46 47 Call call = new Call("1", mtContexts); 48 MtContextCallable mtContextCallable = MtContextCallable. get(call); 49 50 // create after new Task, won't see parent value in in task! 51 MtContextThreadLocal after = new MtContextThreadLocal (); 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 > mtContexts = createTestMtContexts(); 76 77 Call call = new Call("1", mtContexts); 78 MtContextCallable mtContextCallable = MtContextCallable.get(call); 79 80 // create after new Task, won't see parent value in in task! 81 MtContextThreadLocal after = new MtContextThreadLocal (); 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 > mtContexts = createTestMtContexts(); 106 mtContexts.get(PARENT_UNMODIFIED_IN_CHILD).remove(); 107 108 Call call = new Call("1", mtContexts); 109 MtContextCallable mtContextCallable = MtContextCallable.get(call); 110 111 // create after new Task, won't see parent value in in task! 112 MtContextThreadLocal after = new MtContextThreadLocal (); 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 > mtContexts = createTestMtContexts(); 135 136 Call call = new Call("1", mtContexts); 137 MtContextCallable 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 mtContextCallable = MtContextCallable.get(call); 157 assertSame(call, mtContextCallable.getCallable()); 158 } 159 160 @Test 161 public void test_get_idempotent() throws Exception { 162 MtContextCallable 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 call1 = new Call("1", null); 179 Callable call2 = new Call("1", null); 180 Callable call3 = new Call("1", null); 181 182 @SuppressWarnings("unchecked") 183 List > 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 doc
限定符和类型 | 方法和说明 |
---|---|
static |
allOf(java.lang.Iterable
Creates a matcher that matches if the examined object matches
ALL of the specified matchers.
|
static |
allOf(Matcher super T>... matchers)
Creates a matcher that matches if the examined object matches
ALL of the specified matchers.
|
static |
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 |
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 |
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 |
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 |
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 |
any(java.lang.Class
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 |
anyOf(java.lang.Iterable
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static |
anyOf(Matcher super T>... matchers)
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static |
anyOf(Matcher
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static |
anyOf(Matcher
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static |
anyOf(Matcher
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static |
anyOf(Matcher
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static |
anyOf(Matcher
Creates a matcher that matches if the examined object matches
ANY of the specified matchers.
|
static Matcher |
anything()
Creates a matcher that always matches, regardless of the examined object.
|
static Matcher |
anything(java.lang.String description)
Creates a matcher that always matches, regardless of the examined object, but describes itself with the specified
String .
|
static |
both(Matcher super LHS> matcher)
Creates a matcher that matches when both of the specified matchers match the examined object.
|
static Matcher |
containsString(java.lang.String substring)
Creates a matcher that matches if the examined
String contains the specified
String anywhere.
|
static |
describedAs(java.lang.String description, Matcher
Wraps an existing matcher, overriding its description with that specified.
|
static |
either(Matcher super LHS> matcher)
Creates a matcher that matches when either of the specified matchers match the examined object.
|
static Matcher |
endsWith(java.lang.String suffix)
Creates a matcher that matches if the examined
String ends with the specified
String .
|
static |
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 Matcher |
everyItem(Matcher 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 |
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 |
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 |
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 |
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 |
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 |
is(java.lang.Class
已过时。
use isA(Class type) instead.
|
static |
is(Matcher
Decorates another Matcher, retaining its behaviour, but allowing tests to be slightly more expressive.
|
static |
is(T value)
A shortcut to the frequently used
is(equalTo(x)) .
|
static |
isA(java.lang.Class
A shortcut to the frequently used
is(instanceOf(SomeClass.class)) .
|
static |
not(Matcher
Creates a matcher that wraps an existing matcher, but inverts the logic by which it will match.
|
static |
not(T value)
A shortcut to the frequently used
not(equalTo(x)) .
|
static Matcher |
notNullValue()
A shortcut to the frequently used
not(nullValue()) .
|
static |
notNullValue(java.lang.Class
A shortcut to the frequently used
not(nullValue(X.class)).
|
static Matcher |
nullValue()
Creates a matcher that matches if examined object is
null .
|
static |
nullValue(java.lang.Class
Creates a matcher that matches if examined object is
null .
|
static |
sameInstance(T target)
Creates a matcher that matches only when the examined object is the same instance as the specified target object.
|
static Matcher |
startsWith(java.lang.String prefix)
Creates a matcher that matches if the examined
String starts with the specified
String .
|
static |
theInstance(T target)
Creates a matcher that matches only when the examined object is the same instance as the specified target object.
|