Skip to content

Commit e50e66c

Browse files
committed
Add unit tests to cover the methods of AnnotatedMethodDiscovery
Signed-off-by: leelance <[email protected]>
1 parent 0fdb911 commit e50e66c

File tree

2 files changed

+180
-0
lines changed

2 files changed

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

0 commit comments

Comments
 (0)