/*
*
* * Copyright 2010, Unitils.org
* *
* * Licensed 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.unitils.mock.core;
import org.unitils.mock.PartialMock;
import org.unitils.mock.annotation.MatchStatement;
import org.unitils.mock.core.matching.MatchingInvocationHandler;
import org.unitils.mock.mockbehavior.impl.StubMockBehavior;
import static org.unitils.util.ReflectionUtils.copyFields;
/**
* Implementation of a PartialMock.
* For a partial mock, if a method is called that is not mocked, the original behavior will be called.
*
* @author Filip Neven
* @author Tim Ducheyne
* @author Kenny Claes
*/
public class PartialMockObject<T> extends MockObject<T> implements PartialMock<T> {
/**
* Creates a mock of the same type as the given mock prototype with un-capitalized type name + Mock as name, e.g. myServiceMock.
* All instance fields of the given prototype will then be copied to the mock instance. This way you can have a
* pre-initialized instance of the mock (e.g. when there is no default constructor).
*
* If the type mocked instance does not correspond to the declared type, a ClassCastException will occur when the mock
* is used.
*
* @param mockPrototype The instance that will be wrapped with a proxy, use the raw type when mocking generic types, not null
* @param testObject The test object, not null
*/
public PartialMockObject(Object mockPrototype, Object testObject) {
this(null, mockPrototype, testObject);
}
/**
* Creates a mock of the same type as the given mock prototype with the given name.
* All instance fields of the given prototype will then be copied to the mock instance. This way you can have a
* pre-initialized instance of the mock (e.g. when there is no default constructor).
*
* If the type mocked instance does not correspond to the declared type, a ClassCastException will occur when the mock
* is used.
*
* If no name is given the un-capitalized type name + Mock is used, e.g. myServiceMock
*
* @param name The name of the mock, e.g. the field-name, null for the default
* @param mockedInstance The instance that will be wrapped with a proxy, use the raw type when mocking generic types, not null
* @param testObject The test object, not null
*/
public PartialMockObject(String name, Object mockedInstance, Object testObject) {
super(name, mockedInstance.getClass(), testObject);
copyFields(mockedInstance, getMock());
}
/**
* Creates a mock of the given type with un-capitalized type name + Mock as name, e.g. myServiceMock.
*
* There is no .class literal for generic types. Therefore you need to pass the raw type when mocking generic types.
* E.g. Mock<List<String>> myMock = new MockObject("myMock", List.class, this);
*
* If the mocked type does not correspond to the declared type, a ClassCastException will occur when the mock
* is used.
*
* @param mockedType The mock type that will be proxied, use the raw type when mocking generic types, not null
* @param testObject The test object, not null
*/
public PartialMockObject(Class<?> mockedType, Object testObject) {
this(null, mockedType, testObject);
}
/**
* Creates a mock of the given type for the given scenario.
*
* There is no .class literal for generic types. Therefore you need to pass the raw type when mocking generic types.
* E.g. Mock<List<String>> myMock = new MockObject("myMock", List.class, this);
*
* If the mocked type does not correspond to the declared type, a ClassCastException will occur when the mock
* is used.
*
* If no name is given the un-capitalized type name + Mock is used, e.g. myServiceMock
*
* @param name The name of the mock, e.g. the field-name, null for the default
* @param mockedType The mock type that will be proxied, use the raw type when mocking generic types, not null
* @param testObject The test object, not null
*/
public PartialMockObject(String name, Class<?> mockedType, Object testObject) {
super(name, mockedType, testObject);
}
/**
* Stubs out (removes) the behavior of the method when the invocation following
* this call matches the observed behavior. E.g.
* <p/>
* mock.stub().method1();
* <p/>
* will not invoke the actual behavior of method1.
* <p/>
* If the method has a return type, a default value will be returned.
* <p/>
* Note: stubbed methods can still be asserted afterwards: e.g.
* <p/>
* mock.assertInvoked().method1();
*
* @return The proxy instance that will record the method call, not null
*/
@MatchStatement
public T stub() {
MatchingInvocationHandler matchingInvocationHandler = createAlwaysMatchingBehaviorDefiningMatchingInvocationHandler(new StubMockBehavior());
return startMatchingInvocation(matchingInvocationHandler);
}
@Override
protected MockProxy<T> createMockProxy() {
return new PartialMockProxy<T>(name, mockedType, oneTimeMatchingBehaviorDefiningInvocations, alwaysMatchingBehaviorDefiningInvocations, getCurrentScenario(), getMatchingInvocationBuilder());
}
}