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  打赏咖啡

原文地址:https://www.cnblogs.com/funkboy/p/12012551.html

时间: 2024-10-15 22:17:30

jmockit中文网 dubbo bean的相关文章

jmockit 中文网 springbean

如今,我们的很多应用程序是基于Spring的,通过Spring IOC容器来管理我们的Java对象.所以这里单独提出对Spring Bean如何Mock方法. 以上述提到如何Mock类中的提到的AnOrdinaryClass为例,先把这个类配置在Spring的配置文件中 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0" encoding="utf-8"?> <!--su

jmockit中文网备份 @Mocked入门

当@Mocked修饰一个类时 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19  //@Mocked注解用途 public class MockedClassTest {     // 加上了JMockit的API @Mocked, JMockit会帮我们实例化这个对象,不用担心它为null     @Mocked     Locale locale;     // 当@Mocked作用于class     @Test     public void

jMockit中文网备份 @Test&amp;@Injectable

@Injectable 与 @Mocked的不同 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 //@Mocked与@Injectable的不同 public class MockedAndInjectable {     @Test     public void testMocked(@Mocked Locale locale) {         // 静态方法不起作用了,返回了null         

jmockit中文网 expectations 入门

通过上面的例子,我们已经了解了Expectations的作用主要是用于录制.即录制类/对象的调用,返回值是什么. 录制脚本规范 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 new Expectations() {     // 这是一个Expectations匿名内部类     {           // 这是这个内部类的初始化代码块,我们在这里写录制脚本,脚本的格式要遵循下面的约定         //方法调用(可是类的静态方法调用,也可以

jmockit中文网 aop设置

在学习MockUp(API:MockUp)时, MockUp可以自定义方法体,覆盖类原有的方法. JMockit给我们提供了一个特别的方法,用于拦截所有方法,可以让我们在基于被Mock的方法做AOP. 比如我们想测试每个方法的时间性能. 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 //通过在mock时做AOP测试方法的时间性能 public c

jmockit 中文网 构造函数中文代码块

有时候,有些编写不良好的类的构造函数,初始代码块,静态代码块存在大量的初始化逻辑,初始化会报错. 比如,有些类初始化的时候就去连结DB,连不上就报错.这很影响我们的测试程序的运行. 此时,我们需要把这些初始化逻辑Mock掉.用我们的Mock逻辑替代.要Mock这些初始化代码,很简单.见如下的例子: 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 //一个包含初始代码块的普通类  publi

jmockit中文网 定制结果

在学习Expectations(API:Expectations)时   ,在new Expectations{{}}代码中,返回的结果都比较简单.就是一个单一的对象.可是有时,这个返回的结果,可能是需要经历一些业务逻辑计算后,才知道返回什么的,此时,我们就需要定制返回结果了. 还是上例子吧. 还是以上文打招呼的例子来说. 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

jmockit 中文网 mq消息生产者

RocketMQ是我们常用的消息中间件,在运行单元测试时,我们可能不需要真正发送消息(除非是为了测试发送消息),也不想因为连结不上RocketMQ的Broker,NameServer而影响单元测试运行.   那我们该如何Mock RocketMQ消息生产者呢?  请看例子: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 //RocketMQ消息生产者 Mock  public class RocetMQProduce

Spring 实现自定义 bean 的扩展

Spring mvc 提供了扩展 xml 的机制,用来编写自定义的 xml bean ,例如 dubbo 框架,就利用这个机制实现了好多的 dubbo bean,比如 <dubbo:application> .<dubbo:registry> 等等,只要安装这个标准的扩展方式实现配置即可. 扩展自定义 bean 的意义何在 假设我们要使用一个开源框架或者一套 API,我们肯定希望以下两点: 易用性,即配置简单,要配置的地方越少越好 封装性,调用简单,也就是越高层封装越好,少暴露底层