Open ooooo-youwillsee opened 3 years ago
yes
I have one configuration class , for example:
@Configuration
public class XXXConfiguration {
@DubboReference
private SomeService someService;
@Bean
public AnotherService anotherService() {
return new AnotherService() {
public void invoke() {
someService.invokeSomeMethod();
}
}
}
but I can't test , because someService must use register center for Using Spring cloud alibaba
Why not mock dubboReference? Here is a best practice for reference @stonelion.
class ReferenceBeanProcessor implements BeanPostProcessor, BeanFactoryPostProcessor {
private ConfigurableListableBeanFactory beanFactory;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
List<Field> annotatedFields = FieldUtils.getFieldsListWithAnnotation(bean.getClass(), Reference.class);
annotatedFields.addAll(FieldUtils.getFieldsListWithAnnotation(bean.getClass(), com.alibaba.dubbo.config.annotation.Reference.class));
annotatedFields.addAll(FieldUtils.getFieldsListWithAnnotation(bean.getClass(), DubboReference.class));
for (Field field : annotatedFields) {
try {
Class<?> type = field.getType();
String mockBeanName = BeanFactoryUtils.transformedBeanName(type.getSimpleName());
if (!beanFactory.containsBean(mockBeanName)) {
beanFactory.registerSingleton(mockBeanName, Mockito.mock(type));
}
boolean accessible = field.isAccessible();
field.setAccessible(true);
field.set(bean, beanFactory.getBean(type));
field.setAccessible(accessible);
} catch (IllegalAccessException e) {
}
}
return bean;
}
}
The following is my code
@Slf4j
@SpringBootApplication
public class DubboConsumerApplication {
@DubboReference
private UserService userService;
public static void main(String[] args) {
SpringApplication.run(DubboConsumerApplication.class, args);
}
@Bean
public ApplicationRunner testApplicationRunner() {
return __ -> {
String username = userService.getUsernameById(1L);
log.info("username: {}", username);
};
}
}
@SpringBootTest
class DubboConsumerApplicationTest {
@MockBean
private UserService userService;
@Test
public void testDubboReferenceMockBean() {
when(userService.getUsernameById(any())).thenReturn("mock username");
String username1 = userService.getUsernameById(1L);
assertEquals("mock username", username1);
String username2 = userService.getUsernameById(1L);
assertEquals("mock username", username2);
}
}
bootstrap.yml
spring:
application:
name: demo-spring-cloud-dubbo-consumer
dubbo:
protocols:
dubbo:
name: dubbo
port: -1
registry:
address: N/A
# address: 224.5.6.7:2222 # No matter what is configured, the error is reported
scan:
base-packages: com.ooooo
consumer:
check: false
dependencies
mavenBom "com.alibaba.cloud:spring-cloud-alibaba-dependencies:2.2.6.RELEASE"
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR10"
//=========
api('org.springframework.boot:spring-boot-starter-web')
api('com.alibaba.cloud:spring-cloud-starter-dubbo')
api('com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery')
You can find the code here
i have the same need.
the simple @MockBean
annotation mock @dubboReference
is not available.
see: https://github.com/apache/dubbo-spring-boot-project/issues/802
Testing is not important.Either you or your code can run is ok
Do you mean DubboReference‘s dependencies in unit tests?