其他分享
首页 > 其他分享> > jmockit中文网 dubbo bean

jmockit中文网 dubbo bean

作者:互联网

Dubbo是我们常用的RPC框架,在写单元测试需要调用Dubbo消费Bean时,如何模拟Dubbo消费Bean的行为呢?

   就拿发邮件来说,通常,在代码中,我们是调用邮件的Dubbo服务来完成发送邮件的目的,于是我们会在Spring配置好的发邮件的Dubbo消费Bean,
dubbo-consumer.xml

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"     xsi:schemaLocation="http://www.springframework.org/schema/beans             http://www.springframework.org/schema/beans/spring-beans-4.3.xsd             http://dubbo.apache.org/schema/dubbo             http://dubbo.apache.org/schema/dubbo/dubbo.xsd">       <dubbo:application name="consumer-of-dubbo-mock-test" />       <dubbo:registry address="zookeeper://your-zk-address:2181" />     <!-- 生成远程服务代理,可以和本地bean一样使用mailService -->     <dubbo:reference id="mailService" interface="cn.jmockit.demos.MailService" /> </beans>

 

 

   熟悉Dubbo的朋友都知道,上面xml配置是Dubbo的基本配置,配置了dubbo服务的zookeeper地址,还配置了名叫mailService的Dubbo消费Bean,用于在应用程序中发送邮件。
 
   我们在运行单元测试时,如果zookeeper连不上或者mailService的服务提供者不存在,则会导致Spring初始化失败, 而且我们也不希望真正发送邮件(除非是为了测试发送邮件)。于是我们希望对mailService进行Mock。

  下面给出一种Mock Dubbo消费Bean的方案:

  1. 在spring初始化前,对所有Dubbo消费Bean的进行Mock,即<dubbo>标签里的interface都返回本地默认实现。

  2. 如果想对某几个Dubbo消费Bean进行Mock,则自定义Dubbo消费Bean的实现即可。



   请看测试代码:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 //dubbo消费bean Mock  @SuppressWarnings({ "unchecked""rawtypes" }) @ContextConfiguration(locations = { "/META-INF/dubbo-consumer.xml" }) @RunWith(SpringJUnit4ClassRunner.class) public class DubboConsumerBeanMockingTest {     // 这里要@BeforeClass,因为要抢在spring加载dubbo前,对dubbo的消费工厂bean     // ReferenceBean进行mock,不然dubbo可能因为连上不zk或无法找不     // 服务的提供者等原因而无法初始化的,进而,单元测试运行不下去     @BeforeClass     public static void mockDubbo() {         // 你准备mock哪个消费bean         // 比如要对dubbo-consumber.xml里配置的cn.jmockit.demos.MailService这个消费bean进行mock         Map<String, Object> mockMap = new HashMap<String, Object>();         mockMap.put("cn.jmockit.demos.MailService"new MockUp(MailService.class) {             // 在这里书写对这个消费bean进行mock的mock逻辑,想mock哪个方法,就自行添加,注意方法一定要加上@Mock注解哦             @Mock             public boolean sendMail(long userId, String content) {                 // 单元测试时,不需要调用邮件服务器发送邮件,这里统一mock邮件发送成功                 return true;             }         }.getMockInstance());         // 如果要Mock其它的消费bean,自行添加,mockMap.put.....如上         new DubboConsumerBeanMockUp(mockMap);     }       // 现在你使用的dubbo消费bean就是本地mock过的了,并不是指向远程dubbo服务的bean了     @Resource     MailService mailService;       @Test     public void testSendMail() {         long userId = 123456;         String content = "test mail content";         Assert.isTrue(mailService.sendMail(userId, content));     } }

 

 

   上述代码,最关键的就是DubboConsumerBeanMockUp类了,这个类Mock了所有的Dubbo消费Bean.

   源代码如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 //dubbo消费bean的MockUp(伪类) @SuppressWarnings("rawtypes") public class DubboConsumerBeanMockUp extends MockUp<ReferenceBean> {     // 自定义的消费bean mock对象     private Map<String, Object> mockMap;       public DubboConsumerBeanMockUp() {     }       public DubboConsumerBeanMockUp(Map<String, Object> mockMap) {         this.mockMap = mockMap;     }       // 对ReferenceBean的getObject方法的Mock     @SuppressWarnings("unchecked")     @Mock     public Object getObject(Invocation inv) throws Exception {         ReferenceBean ref = inv.getInvokedInstance();         String interfaceName = ref.getInterface();         Object mock = mockMap.get(interfaceName);         if (mock != null) {             return mock;         }         return (new MockUp(Class.forName(interfaceName)) {         }).getMockInstance();     } }

 


© JMockit中文网 2018  打赏咖啡

标签:jmockit,dubbo,Dubbo,Bean,bean,mock,Mock
来源: https://www.cnblogs.com/funkboy/p/12012551.html