1 /*
2  * Copyright (C) 2023 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 package com.android.modules.utils.testing;
17 
18 import com.android.modules.utils.testing.AbstractExtendedMockitoRule.AbstractBuilder;
19 import com.android.modules.utils.testing.ExtendedMockitoRule.Builder;
20 
21 import java.lang.annotation.ElementType;
22 import java.lang.annotation.Repeatable;
23 import java.lang.annotation.Retention;
24 import java.lang.annotation.RetentionPolicy;
25 import java.lang.annotation.Target;
26 
27 /**
28  * Rule to make it easier to use Extended Mockito:
29  *
30  * <ul>
31  *   <li>Automatically creates and finishes the mock session.
32  *   <li>Provides multiple ways to set which classes must be statically mocked or spied
33  *   <li>Automatically starts mocking (so tests don't need a mockito runner or rule)
34  *   <li>Automatically clears the inlined mocks at the end (to avoid OOM)
35  *   <li>Allows other customization like strictness
36  * </ul>
37  * <p>Typical usage:
38  * <pre class="prettyprint">
39  * &#064;Rule
40  * public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
41  *     .spyStatic(SomeClassWithStaticMethodsToBeMocked)
42  *     .build();
43  * </pre>
44  */
45 public final class ExtendedMockitoRule extends
46         AbstractExtendedMockitoRule<ExtendedMockitoRule, Builder> {
47 
ExtendedMockitoRule(Builder builder)48     public ExtendedMockitoRule(Builder builder) {
49         super(builder);
50     }
51     /**
52      * Builder for the rule.
53      */
54     public static final class Builder extends AbstractBuilder<ExtendedMockitoRule, Builder> {
55 
56         /**
57          * Constructs a builder for the giving test instance (typically {@code this}) and initialize
58          * mocks on it.
59          */
Builder(Object testClassInstance)60         public Builder(Object testClassInstance) {
61             super(testClassInstance);
62         }
63 
64         /**
65          * Constructs a builder that doesn't initialize mocks.
66          *
67          * <p>Typically used on test classes that already initialize mocks somewhere else.
68          */
Builder()69         public Builder() {
70             super();
71         }
72 
73         /**
74          * Builds the rule.
75          */
build()76         public ExtendedMockitoRule build() {
77             return new ExtendedMockitoRule(this);
78         }
79     }
80 
81     @Retention(RetentionPolicy.RUNTIME)
82     @Target({ElementType.METHOD, ElementType.TYPE})
83     @Repeatable(SpyStaticClasses.class)
84     public @interface SpyStatic {
value()85         Class<?> value();
86     }
87 
88     @Retention(RetentionPolicy.RUNTIME)
89     @Target({ElementType.METHOD, ElementType.TYPE})
90     public @interface SpyStaticClasses {
value()91         SpyStatic[] value();
92     }
93 
94     @Retention(RetentionPolicy.RUNTIME)
95     @Target({ElementType.METHOD, ElementType.TYPE})
96     @Repeatable(MockStaticClasses.class)
97     public @interface MockStatic {
value()98         Class<?> value();
99     }
100 
101     @Retention(RetentionPolicy.RUNTIME)
102     @Target({ElementType.METHOD, ElementType.TYPE})
103     public @interface MockStaticClasses {
value()104         MockStatic[] value();
105     }
106 }
107