Skip to content

Commit 967d00c

Browse files
leehautilayaperumalg
authored andcommitted
Add unit tests to cover the methods of AnnotatedMethodDiscovery
Signed-off-by: leelance <leehaut@gmail.com>
1 parent 8b9f730 commit 967d00c

File tree

2 files changed

+190
-0
lines changed

2 files changed

+190
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright 2025-2025 the original author or authors.
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+
* https://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 org.springframework.ai.mcp.annotation.spring.scan;
18+
19+
import java.lang.annotation.Annotation;
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
import java.util.List;
25+
import java.util.Set;
26+
27+
import org.junit.jupiter.api.Test;
28+
29+
import org.springframework.aot.generate.GenerationContext;
30+
import org.springframework.aot.hint.RuntimeHints;
31+
import org.springframework.aot.hint.TypeHint;
32+
import org.springframework.aot.hint.TypeReference;
33+
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution;
34+
import org.springframework.beans.factory.aot.BeanFactoryInitializationCode;
35+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
36+
import org.springframework.beans.factory.support.RootBeanDefinition;
37+
38+
import static org.assertj.core.api.Assertions.assertThat;
39+
import static org.mockito.Mockito.mock;
40+
import static org.mockito.Mockito.when;
41+
42+
/**
43+
* Unit Tests for {@link AbstractAnnotatedMethodBeanFactoryInitializationAotProcessor}.
44+
*
45+
* @author lance
46+
*/
47+
class AbstractAnnotatedMethodBeanFactoryInitializationAotProcessorTests {
48+
49+
@Test
50+
void testProcessAheadOfTime() {
51+
// register bean(AnnotatedBean,PlainBean)
52+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
53+
beanFactory.registerBeanDefinition(AnnotatedBean.class.getName(), new RootBeanDefinition(AnnotatedBean.class));
54+
beanFactory.registerBeanDefinition(PlainBean.class.getName(), new RootBeanDefinition(PlainBean.class));
55+
56+
PlainBean plainBean = beanFactory.getBean(PlainBean.class);
57+
assertThat(plainBean).isNotNull();
58+
59+
// create AbstractAnnotatedMethodBeanFactoryInitializationAotProcessor
60+
Set<Class<? extends Annotation>> annotations = Set.of(MyAnnotation.class);
61+
AbstractAnnotatedMethodBeanFactoryInitializationAotProcessor processor = new AbstractAnnotatedMethodBeanFactoryInitializationAotProcessor(
62+
annotations);
63+
64+
// execute processAheadOfTime
65+
BeanFactoryInitializationAotContribution aotContribution = processor.processAheadOfTime(beanFactory);
66+
assertThat(aotContribution).isNotNull();
67+
68+
// execute Contribution
69+
GenerationContext generationContext = mock(GenerationContext.class);
70+
when(generationContext.getRuntimeHints()).thenReturn(new RuntimeHints());
71+
72+
BeanFactoryInitializationCode initializationCode = mock(BeanFactoryInitializationCode.class);
73+
aotContribution.applyTo(generationContext, initializationCode);
74+
75+
// valid hints bean exist?
76+
List<TypeHint> typeHints = generationContext.getRuntimeHints().reflection().typeHints().toList();
77+
assertThat(typeHints).isNotNull().hasSize(1);
78+
79+
TypeReference type = typeHints.get(0).getType();
80+
assertThat(type).matches(t -> t.getName().equals(AnnotatedBean.class.getName()))
81+
.doesNotMatch(t -> t.getName().equals(PlainBean.class.getName()));
82+
}
83+
84+
@Target(ElementType.METHOD)
85+
@Retention(RetentionPolicy.RUNTIME)
86+
@interface MyAnnotation {
87+
88+
}
89+
90+
/**
91+
* test bean
92+
*/
93+
static class AnnotatedBean {
94+
95+
@MyAnnotation
96+
public void doSomething() {
97+
}
98+
99+
}
100+
101+
static class PlainBean {
102+
103+
public void nothing() {
104+
}
105+
106+
}
107+
108+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright 2025-2025 the original author or authors.
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+
* https://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 org.springframework.ai.mcp.annotation.spring.scan;
18+
19+
import java.lang.annotation.Annotation;
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
import java.util.Set;
25+
26+
import org.junit.jupiter.api.Test;
27+
28+
import static org.assertj.core.api.Assertions.assertThat;
29+
30+
/**
31+
* Unit Tests for {@link AnnotatedMethodDiscovery}.
32+
*
33+
* @author lance
34+
*/
35+
class AnnotatedMethodDiscoveryTests {
36+
37+
@Test
38+
void testScanAnnotationMethod() {
39+
Set<Class<? extends Annotation>> annotations = Set.of(MyAnnotation.class, AnotherAnnotation.class);
40+
AnnotatedMethodDiscovery discovery = new AnnotatedMethodDiscovery(annotations);
41+
Set<Class<? extends Annotation>> scanned = discovery.scan(PlainClass.class);
42+
43+
assertThat(scanned).containsExactlyInAnyOrder(MyAnnotation.class, AnotherAnnotation.class);
44+
}
45+
46+
@Test
47+
void testReturnEmpty() {
48+
Set<Class<? extends Annotation>> annotations = Set.of(MyAnnotation.class);
49+
AnnotatedMethodDiscovery discovery = new AnnotatedMethodDiscovery(annotations);
50+
Set<Class<? extends Annotation>> scanned = discovery.scan(Set.class);
51+
52+
assertThat(scanned).isEmpty();
53+
}
54+
55+
@Target(ElementType.METHOD)
56+
@Retention(RetentionPolicy.RUNTIME)
57+
@interface MyAnnotation {
58+
59+
}
60+
61+
@Target(ElementType.METHOD)
62+
@Retention(RetentionPolicy.RUNTIME)
63+
@interface AnotherAnnotation {
64+
65+
}
66+
67+
static class PlainClass {
68+
69+
@MyAnnotation
70+
public void methodA() {
71+
}
72+
73+
@AnotherAnnotation
74+
public void methodB() {
75+
}
76+
77+
public void methodC() {
78+
}
79+
80+
}
81+
82+
}

0 commit comments

Comments
 (0)