/* * * * 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.report.impl; import org.unitils.mock.core.BehaviorDefiningInvocation; import org.unitils.mock.core.ObservedInvocation; import org.unitils.mock.core.proxy.ProxyInvocation; import org.unitils.mock.mockbehavior.MockBehavior; import org.unitils.mock.mockbehavior.impl.DefaultValueReturningMockBehavior; import org.unitils.mock.mockbehavior.impl.OriginalBehaviorInvokingMockBehavior; import java.util.*; /** * A view that displays the details of the observed invocations. The details include: * <ul> * <li>the location where the invocation was invoked</li> * <li>the mock behavior that was executed</li> * <li>the location where this mock behavior was defined</li> * </ul> * Example: <pre><code> * 1. mock.method1() -> string1 * * - string1 -> "1234567891234567890" * - Observed at MyTest.testMethod(MyTest.java:75) * - Behavior defined at MyTest.myTest(MyTest.java:37) * * * 2. mock.method1("value", 4) -> null * * - Observed at MyTest.testMethod(MyTest.java:77) * - No behavior defined, returned default value. * <code></pre> * * @author Kenny Claes * @author Filip Neven * @author Tim Ducheyne */ public class DetailedObservedInvocationsReport extends ObservedInvocationsReport { public DetailedObservedInvocationsReport(Object testedObject) { super(testedObject); } /** * Creates a string representation of the given scenario as described in the class javadoc. * * @return The string representation, not null */ @Override public String createReport(List<ObservedInvocation> observedInvocations) { StringBuilder result = new StringBuilder(); Map<Object, FormattedObject> allLargeObjects = new IdentityHashMap<Object, FormattedObject>(); Map<Class<?>, Integer> largeObjectNameIndexes = new HashMap<Class<?>, Integer>(); // append all invocations int invocationIndex = 1; for (ObservedInvocation observedInvocation : observedInvocations) { List<FormattedObject> currentLargeObjects = new ArrayList<FormattedObject>(); result.append(invocationIndex++); result.append(". "); result.append(formatObservedInvocation(observedInvocation, currentLargeObjects, allLargeObjects, largeObjectNameIndexes)); result.append("\n"); result.append(formatLargeObjects(currentLargeObjects)); result.append(formatInvokedAt(observedInvocation)); result.append(formatBehaviorDetails(observedInvocation)); result.append("\n"); } return result.toString(); } /** * Creates a string representation of the details of the given invocation. This will give information about * where the invocation occurred. * * @param proxyInvocation The invocation to format, not null * @return The string representation, not null */ protected String formatInvokedAt(ProxyInvocation proxyInvocation) { StringBuilder result = new StringBuilder(); result.append("- Observed at "); result.append(proxyInvocation.getInvokedAt()); result.append("\n"); return result.toString(); } /** * Creates a string representation of the behavior details of the given invocation. This will give information about * where the mock behavior was recorded. * * @param observedInvocation The invocation to format, not null * @return The string representation, not null */ protected String formatBehaviorDetails(ObservedInvocation observedInvocation) { StringBuilder result = new StringBuilder(); BehaviorDefiningInvocation behaviorDefiningInvocation = observedInvocation.getBehaviorDefiningInvocation(); if (behaviorDefiningInvocation != null) { result.append("- Behavior defined at "); result.append(behaviorDefiningInvocation.getInvokedAt()); result.append("\n"); return result.toString(); } MockBehavior mockBehavior = observedInvocation.getMockBehavior(); if (mockBehavior != null) { if (mockBehavior instanceof OriginalBehaviorInvokingMockBehavior) { result.append("- No behavior defined, executed original method behavior."); } else if (mockBehavior instanceof DefaultValueReturningMockBehavior) { result.append("- No behavior defined, returned default value."); } else { result.append("- No behavior defined, executed default behavior."); } result.append("\n"); } return result.toString(); } /** * Format the values that were to long to be displayed inline * * @param largeObjects The large value representations, not null * @return The string representation, not null */ protected String formatLargeObjects(List<FormattedObject> largeObjects) { StringBuilder result = new StringBuilder(); List<String> usedNames = new ArrayList<String>(); if (!largeObjects.isEmpty()) { for (FormattedObject largeObject : largeObjects) { String name = largeObject.getName(); if (usedNames.contains(name)) { // skip doubles continue; } usedNames.add(name); String representation = largeObject.getRepresentation(); result.append("- "); result.append(name); result.append(" -> "); result.append(representation); result.append("\n"); } } return result.toString(); } }