CoreMatchers和Assert配合做junit

最近在读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<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 doc

限定符和类型方法和说明
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 Iterables 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 Iterables 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 Iterables 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 Iterables that matches when consecutive passes over the examined Iterable yield at least one item that is matched by the corresponding matcher from the specifieditemMatchers.
static <T> Matcher<java.lang.Iterable<T>> hasItems(T... items)
Creates a matcher for Iterables 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.
posted @ 2015-12-15 18:53  kangye1014  阅读(652)  评论(0编辑  收藏  举报