• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.adservices.shared.testing;
18 
19 import com.android.adservices.shared.testing.concurrency.DeviceSideSyncCallback;
20 import com.android.adservices.shared.testing.concurrency.SyncCallbackFactory;
21 import com.android.adservices.shared.testing.concurrency.SyncCallbackSettings;
22 import com.android.adservices.shared.testing.mockito.MockitoHelper;
23 
24 import org.mockito.invocation.InvocationOnMock;
25 import org.mockito.stubbing.Answer;
26 
27 /**
28  * {@code SyncCallback} to be used when setting Mockito expectations with an {@link Answer}.
29  *
30  * @param <T> return type of the method being "answered".
31  */
32 public final class AnswerSyncCallback<T> extends DeviceSideSyncCallback implements Answer<T> {
33 
34     @Nullable private final T mAnswer;
35     @Nullable private final Throwable mFailure;
36 
AnswerSyncCallback(T answer, Throwable failure, int numberOfExpectedCalls)37     private AnswerSyncCallback(T answer, Throwable failure, int numberOfExpectedCalls) {
38         this(
39                 answer,
40                 failure,
41                 SyncCallbackFactory.newSettingsBuilder()
42                         .setExpectedNumberCalls(numberOfExpectedCalls)
43                         .build());
44     }
45 
AnswerSyncCallback(T answer, Throwable failure, SyncCallbackSettings settings)46     private AnswerSyncCallback(T answer, Throwable failure, SyncCallbackSettings settings) {
47         super(settings);
48         mAnswer = answer;
49         mFailure = failure;
50     }
51 
52     /**
53      * Convenience method for {@link #forVoidAnswers(SyncCallbackSettings)} using a {@link
54      * SyncCallbackSettings settings} that expects just 1 call.
55      */
forSingleVoidAnswer()56     public static AnswerSyncCallback<Void> forSingleVoidAnswer() {
57         return new AnswerSyncCallback<Void>(
58                 /* answer= */ null, /* failure= */ null, /* numberOfExpectedCalls= */ 1);
59     }
60 
61     /**
62      * Convenience method for {@link #forAnswers(SyncCallbackSettings)} using a {@link
63      * SyncCallbackSettings settings} that expects just 1 call.
64      */
forSingleAnswer(A answer)65     public static <A> AnswerSyncCallback<A> forSingleAnswer(A answer) {
66         return new AnswerSyncCallback<A>(
67                 answer, /* failure= */ null, /* numberOfExpectedCalls= */ 1);
68     }
69 
70     /**
71      * Convenience method for {@link #forVoidAnswers(SyncCallbackSettings)} using a {@link
72      * SyncCallbackSettings settings} that expects {@code numberOfExpectedCalls} calls.
73      */
forMultipleVoidAnswers(int numberOfExpectedCalls)74     public static AnswerSyncCallback<Void> forMultipleVoidAnswers(int numberOfExpectedCalls) {
75         return new AnswerSyncCallback<>(
76                 /* answer= */ null, /* failure= */ null, numberOfExpectedCalls);
77     }
78 
79     /**
80      * Convenience method for {@link #forAnswers(SyncCallbackSettings)} using a {@link
81      * SyncCallbackSettings settings} that expects {@code numberOfExpectedCalls} calls.
82      */
forMultipleAnswers( A answer, int numberOfExpectedCalls)83     public static <A> AnswerSyncCallback<A> forMultipleAnswers(
84             A answer, int numberOfExpectedCalls) {
85         return new AnswerSyncCallback<A>(answer, /* failure= */ null, numberOfExpectedCalls);
86     }
87 
88     /**
89      * Factory method for answers that return {@code Void} and take a generic {@link
90      * SyncCallbackSettings}.
91      */
forVoidAnswers(SyncCallbackSettings settings)92     public static AnswerSyncCallback<Void> forVoidAnswers(SyncCallbackSettings settings) {
93         return new AnswerSyncCallback<>(/* answer= */ null, /* failure= */ null, settings);
94     }
95 
96     /** Factory method for answers that return non-{@code Void}. */
forAnswers(A answer, SyncCallbackSettings settings)97     public static <A> AnswerSyncCallback<A> forAnswers(A answer, SyncCallbackSettings settings) {
98         return new AnswerSyncCallback<A>(answer, /* failure= */ null, settings);
99     }
100 
101     /**
102      * Factory method for {@link Answer}s that should thrown an exception.
103      *
104      * @param clazz type of the object that should be returned by the {@link Answer}
105      * @param failure exception that will be thrown.
106      */
forSingleFailure(Class<A> clazz, Throwable failure)107     public static <A> AnswerSyncCallback<A> forSingleFailure(Class<A> clazz, Throwable failure) {
108         return new AnswerSyncCallback<A>(
109                 /* answer= */ null, failure, /* numberOfExpectedCalls= */ 1);
110     }
111 
112     @Override
answer(InvocationOnMock invocation)113     public T answer(InvocationOnMock invocation) throws Throwable {
114         String invocationString = MockitoHelper.toString(invocation);
115         super.internalSetCalled("answer(" + invocationString + ")");
116         if (mFailure != null) {
117             logV("Throwing '%s' on %s", mFailure, invocationString);
118             throw mFailure;
119         }
120         logV("Answering '%s' on %s", mAnswer, invocationString);
121         return mAnswer;
122     }
123 }
124