Skip to content

Commit d166920

Browse files
committed
Add answer in annotation
Signed-off-by: Jorge Bescos Gascon <[email protected]>
1 parent c1b42fe commit d166920

File tree

3 files changed

+92
-8
lines changed

3 files changed

+92
-8
lines changed

microprofile/testing/mock-beans/src/main/java/io/helidon/microprofile/testing/mockbeans/MockBean.java

+8
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
2323

24+
import org.mockito.Answers;
25+
2426
/**
2527
* A field annotated with @MockBean will be mocked by Mockito
2628
* and injected in every place it is referenced.
@@ -29,4 +31,10 @@
2931
@Target({ElementType.FIELD, ElementType.PARAMETER})
3032
public @interface MockBean {
3133

34+
/**
35+
* The {@link Answers} type to use on the mock.
36+
* Defaults to {@link Answers#RETURNS_DEFAULTS}
37+
* @return the answer type
38+
*/
39+
Answers answer() default Answers.RETURNS_DEFAULTS;
3240
}

microprofile/testing/mock-beans/src/main/java/io/helidon/microprofile/testing/mockbeans/MockBeansCdiExtension.java

+9-8
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
package io.helidon.microprofile.testing.mockbeans;
1717

1818
import java.lang.reflect.Field;
19-
import java.util.HashSet;
19+
import java.util.HashMap;
2020
import java.util.List;
21+
import java.util.Map;
2122
import java.util.Set;
2223

2324
import jakarta.enterprise.context.ApplicationScoped;
@@ -38,7 +39,7 @@
3839
*/
3940
public class MockBeansCdiExtension implements Extension {
4041

41-
private final Set<Class<?>> mocks = new HashSet<>();
42+
private final Map<Class<?>, MockBean> mocks = new HashMap<>();
4243

4344
void processMockBean(@Observes @WithAnnotations(MockBean.class) ProcessAnnotatedType<?> obj) throws Exception {
4445
var configurator = obj.configureAnnotatedType();
@@ -49,7 +50,7 @@ void processMockBean(@Observes @WithAnnotations(MockBean.class) ProcessAnnotated
4950
// Adds @Inject to be more user friendly
5051
field.add(InjectLiteral.INSTANCE);
5152
Class<?> fieldType = f.getType();
52-
mocks.add(fieldType);
53+
mocks.put(fieldType, mockBean);
5354
}
5455
});
5556
configurator.constructors().forEach(constructor -> {
@@ -62,16 +63,16 @@ private void processMockBeanParameters(List<? extends AnnotatedParameter<?>> par
6263
MockBean mockBean = parameter.getAnnotation(MockBean.class);
6364
if (mockBean != null) {
6465
Class<?> parameterType = parameter.getJavaParameter().getType();
65-
mocks.add(parameterType);
66+
mocks.put(parameterType, mockBean);
6667
}
6768
});
6869
}
6970

7071
void registerOtherBeans(@Observes AfterBeanDiscovery event, BeanManager beanManager) {
7172
// Register all mocks
72-
mocks.forEach(type -> {
73+
mocks.entrySet().forEach(entry -> {
7374
event.addBean()
74-
.addType(type)
75+
.addType(entry.getKey())
7576
.scope(ApplicationScoped.class)
7677
.alternative(true)
7778
.createWith(inst -> {
@@ -80,9 +81,9 @@ void registerOtherBeans(@Observes AfterBeanDiscovery event, BeanManager beanMana
8081
Bean<?> bean = beans.iterator().next();
8182
MockSettings mockSettings = (MockSettings) beanManager.getReference(bean, MockSettings.class,
8283
beanManager.createCreationalContext(null));
83-
return Mockito.mock(type, mockSettings);
84+
return Mockito.mock(entry.getKey(), mockSettings);
8485
} else {
85-
return Mockito.mock(type);
86+
return Mockito.mock(entry.getKey(), Mockito.withSettings().defaultAnswer(entry.getValue().answer()));
8687
}
8788
})
8889
.priority(0);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2024 Oracle and/or its affiliates.
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 io.helidon.microprofile.tests.testing.junit5;
18+
19+
import static org.hamcrest.CoreMatchers.is;
20+
import static org.hamcrest.MatcherAssert.assertThat;
21+
22+
import jakarta.enterprise.inject.Produces;
23+
import jakarta.inject.Inject;
24+
import jakarta.ws.rs.GET;
25+
import jakarta.ws.rs.Path;
26+
import jakarta.ws.rs.client.WebTarget;
27+
28+
import io.helidon.microprofile.testing.junit5.AddBean;
29+
import io.helidon.microprofile.testing.junit5.HelidonTest;
30+
import io.helidon.microprofile.testing.mockbeans.MockBean;
31+
32+
import org.junit.jupiter.api.Test;
33+
import org.mockito.Answers;
34+
import org.mockito.MockSettings;
35+
import org.mockito.Mockito;
36+
37+
@HelidonTest
38+
@AddBean(TestMockBeanAnswer.Resource.class)
39+
@AddBean(TestMockBeanAnswer.Service.class)
40+
class TestMockBeanAnswer {
41+
42+
@MockBean(answer = Answers.CALLS_REAL_METHODS)
43+
private Service service;
44+
@Inject
45+
private WebTarget target;
46+
47+
@Test
48+
void injectionTest() {
49+
String response = target.path("/test").request().get(String.class);
50+
assertThat(response, is("Not Mocked"));
51+
Mockito.when(service.test()).thenReturn("Mocked");
52+
response = target.path("/test").request().get(String.class);
53+
assertThat(response, is("Mocked"));
54+
}
55+
56+
@Path("/test")
57+
public static class Resource {
58+
59+
@Inject
60+
private Service service;
61+
62+
@GET
63+
public String test() {
64+
return service.test();
65+
}
66+
}
67+
68+
static class Service {
69+
70+
String test() {
71+
return "Not Mocked";
72+
}
73+
74+
}
75+
}

0 commit comments

Comments
 (0)