| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.hadoop.test; |
| |
| import static org.mockito.Mockito.*; |
| |
| /** |
| * Helper class to create one-liner stubs, so that instead of: <pre> |
| * SomeType someDescriptiveMock = mock(SomeType.class); |
| * when(someDescriptiveMock.someMethod()).thenReturn(someValue);</pre> |
| * <p>You can now do: <pre> |
| * SomeType someDescriptiveMock = make(stub(SomeType.class) |
| * .returning(someValue).from.someMethod());</pre> |
| */ |
| public class MockitoMaker { |
| |
| /** |
| * Create a mock object from a mocked method call. |
| * |
| * @param <T> type of mocked object |
| * @param methodCall for mocked object |
| * @return mocked object |
| */ |
| @SuppressWarnings("unchecked") |
| public static <T> T make(Object methodCall) { |
| StubBuilder<T> sb = StubBuilder.current(); |
| when(methodCall).thenReturn(sb.firstReturn, sb.laterReturns); |
| return (T) StubBuilder.current().from; |
| } |
| |
| /** |
| * Create a stub builder of a mocked object. |
| * |
| * @param <T> type of the target object to be mocked |
| * @param target class of the target object to be mocked |
| * @return the stub builder of the mocked object |
| */ |
| public static <T> StubBuilder<T> stub(Class<T> target) { |
| return new StubBuilder<T>(mock(target)); |
| } |
| |
| /** |
| * Builder class for stubs |
| * @param <T> type of the object to be mocked |
| */ |
| public static class StubBuilder<T> { |
| |
| /** |
| * The target mock object |
| */ |
| public final T from; |
| |
| // We want to be able to use this even when the tests are run in parallel. |
| @SuppressWarnings("rawtypes") |
| private static final ThreadLocal<StubBuilder> tls = |
| new ThreadLocal<StubBuilder>() { |
| @Override protected StubBuilder initialValue() { |
| return new StubBuilder(); |
| } |
| }; |
| |
| private Object firstReturn = null; |
| private Object[] laterReturns = {}; |
| |
| /** |
| * Default constructor for the initial stub builder |
| */ |
| public StubBuilder() { |
| this.from = null; |
| } |
| |
| /** |
| * Construct a stub builder with a mock instance |
| * |
| * @param mockInstance the mock object |
| */ |
| public StubBuilder(T mockInstance) { |
| tls.set(this); |
| this.from = mockInstance; |
| } |
| |
| /** |
| * Get the current stub builder from thread local |
| * |
| * @param <T> |
| * @return the stub builder of the mocked object |
| */ |
| @SuppressWarnings("unchecked") |
| public static <T> StubBuilder<T> current() { |
| return tls.get(); |
| } |
| |
| /** |
| * Set the return value for the current stub builder |
| * |
| * @param value the return value |
| * @return the stub builder |
| */ |
| public StubBuilder<T> returning(Object value) { |
| this.firstReturn = value; |
| return this; |
| } |
| |
| /** |
| * Set the return values for the current stub builder |
| * |
| * @param value the first return value |
| * @param values the return values for later invocations |
| * @return the stub builder |
| */ |
| public StubBuilder<T> returning(Object value, Object... values) { |
| this.firstReturn = value; |
| this.laterReturns = values; |
| return this; |
| } |
| } |
| } |