View Javadoc
1   /*
2    * MIT License
3    * Copyright (c) 2006-2025 JMockit developers
4    * See LICENSE file for full license text.
5    */
6   package mockit;
7   
8   import static org.junit.jupiter.api.Assertions.assertArrayEquals;
9   import static org.junit.jupiter.api.Assertions.assertEquals;
10  import static org.junit.jupiter.api.Assertions.assertFalse;
11  import static org.junit.jupiter.api.Assertions.assertNull;
12  import static org.junit.jupiter.api.Assertions.assertSame;
13  
14  import edu.umd.cs.findbugs.annotations.NonNull;
15  
16  import jakarta.annotation.Resource;
17  
18  import java.lang.annotation.Annotation;
19  
20  import mockit.integration.junit5.JMockitExtension;
21  
22  import org.checkerframework.checker.index.qual.NonNegative;
23  import org.junit.jupiter.api.Test;
24  import org.junit.jupiter.api.extension.ExtendWith;
25  
26  /**
27   * The Class MockedAnnotationsTest.
28   */
29  @ExtendWith(JMockitExtension.class)
30  class MockedAnnotationsTest {
31  
32      /**
33       * The Interface MyAnnotation.
34       */
35      public @interface MyAnnotation {
36  
37          /**
38           * Value.
39           *
40           * @return the string
41           */
42          String value();
43  
44          /**
45           * Flag.
46           *
47           * @return true, if successful
48           */
49          boolean flag() default true;
50  
51          /**
52           * Values.
53           *
54           * @return the string[]
55           */
56          String[] values() default {};
57      }
58  
59      /**
60       * Specify values for annotation attributes.
61       *
62       * @param a
63       *            the a
64       */
65      @Test
66      void specifyValuesForAnnotationAttributes(@Mocked final MyAnnotation a) {
67          assertSame(MyAnnotation.class, a.annotationType());
68  
69          new Expectations() {
70              {
71                  a.flag();
72                  result = false;
73                  a.value();
74                  result = "test";
75                  a.values();
76                  returns("abc", "dEf");
77              }
78          };
79  
80          assertFalse(a.flag());
81          assertEquals("test", a.value());
82          assertArrayEquals(new String[] { "abc", "dEf" }, a.values());
83      }
84  
85      /**
86       * Verify uses of annotation attributes.
87       *
88       * @param a
89       *            the a
90       */
91      @Test
92      void verifyUsesOfAnnotationAttributes(@Mocked final MyAnnotation a) {
93          new Expectations() {
94              {
95                  a.value();
96                  result = "test";
97                  times = 2;
98                  a.values();
99                  returns("abc", "dEf");
100             }
101         };
102 
103         // Same rule for regular methods applies (ie, if no return value was recorded, invocations
104         // will get the default for the return type).
105         assertFalse(a.flag());
106 
107         assertEquals("test", a.value());
108         assertArrayEquals(new String[] { "abc", "dEf" }, a.values());
109         a.value();
110 
111         new FullVerifications() {
112             {
113                 // Mocked methods called here always return the default value according to return type.
114                 a.flag();
115             }
116         };
117     }
118 
119     /**
120      * The Interface AnInterface.
121      */
122     @Resource
123     public interface AnInterface {
124     }
125 
126     /**
127      * Mocking an annotated public interface.
128      *
129      * @param mock
130      *            the mock
131      */
132     @Test
133     void mockingAnAnnotatedPublicInterface(@Mocked AnInterface mock) {
134         Annotation[] mockClassAnnotations = mock.getClass().getAnnotations();
135 
136         assertEquals(0, mockClassAnnotations.length);
137     }
138 
139     /**
140      * The Class ClassWithNullabilityAnnotations.
141      */
142     static class ClassWithNullabilityAnnotations {
143 
144         /**
145          * Do something.
146          *
147          * @param i
148          *            the i
149          * @param obj
150          *            the obj
151          *
152          * @return the string
153          */
154         @NonNull
155         String doSomething(@NonNegative int i, @NonNull Object obj) {
156             return "";
157         }
158     }
159 
160     /**
161      * Mock class with nullability annotations.
162      *
163      * @param mock
164      *            the mock
165      */
166     @Test
167     void mockClassWithNullabilityAnnotations(@Injectable final ClassWithNullabilityAnnotations mock) {
168         new Expectations() {
169             {
170                 mock.doSomething(anyInt, any);
171                 result = "test";
172             }
173         };
174 
175         assertEquals("test", mock.doSomething(123, "test"));
176     }
177 
178     /**
179      * The Class ClassWithAnnotatedField.
180      */
181     static final class ClassWithAnnotatedField {
182         /** The a field. */
183         @Resource(type = int.class)
184         Object aField;
185     }
186 
187     /**
188      * Mock class having field annotated with attribute having A primitive class as value.
189      *
190      * @param mock
191      *            the mock
192      */
193     @Test
194     void mockClassHavingFieldAnnotatedWithAttributeHavingAPrimitiveClassAsValue(@Mocked ClassWithAnnotatedField mock) {
195         assertNull(mock.aField);
196     }
197 }